#
CONFIG_MTD=m
# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=m
+CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CONCAT=m
CONFIG_MTD_REDBOOT_PARTS=m
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
#
# User Modules And Translation Layers
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
CONFIG_WAN_ROUTER=m
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_BT_HCIBLUECARD=m
CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
-CONFIG_TUX=m
-
-#
-# TUX options
-#
-CONFIG_TUX_EXTCGI=y
-# CONFIG_TUX_EXTENDED_LOG is not set
-# CONFIG_TUX_DEBUG is not set
+# CONFIG_TUX is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_DEBUG_KERNEL=y
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK=y
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_INFO=y
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_MTD_PARTITIONS=m
CONFIG_MTD_CONCAT=m
CONFIG_MTD_REDBOOT_PARTS=m
-CONFIG_MTD_CMDLINE_PARTS=m
-
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_PARTITIONS=y
#
# User Modules And Translation Layers
#
#
# Tux
#
-CONFIG_TUX=m
+# CONFIG_TUX is not set
CONFIG_TUX_EXTCGI=y
# CONFIG_TUX_EXTENDED_LOG is not set
# CONFIG_TUX_DEBUG is not set
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK=y
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_FRAME_POINTER is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_DRIVER is not set
CONFIG_CRYPTO_SIGNATURE_DSA=y
CONFIG_CRYPTO_MPILIB=y
CONFIG_CRYPTO_TEA=m
-
+CONFIG_CRYPTO_KHAZAD=m
#
# Library routines
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
-CONFIG_TUX=m
+# CONFIG_TUX is not set
CONFIG_NVRAM=m
CONFIG_IBM_ASM=m
CONFIG_CRYPTO_AES_586=m
CAST5 algorithm contributors:
Kartikey Mahendra Bhatt (original developers unknown, FSF copyright).
+TEA/XTEA algorithm contributors:
+ Aaron Grothe
+
+Khazad algorithm contributors:
+ Aaron Grothe
+
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
Please send any credits updates or corrections to:
loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
+ int (*check_flags)(int);
+ int (*dir_notify)(struct file *, unsigned long);
};
locking rules:
sendfile: no
sendpage: no
get_unmapped_area: no
+check_flags: no
+dir_notify: no
->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you
A lot of the assembly code currently runs in real mode, which means
absolute addresses are used instead of virtual addresses as in the
rest of the kernel. To translate an absolute address to a virtual
-address you can lookup in System.map, add __PAGE_OFFSET (0xc0000000
+address you can lookup in System.map, add __PAGE_OFFSET (0x10000000
currently).
code tried to access.
Typical values for the System Responder address are addresses larger
-than __PAGE_OFFSET (0xc0000000) which mean a virtual address didn't
+than __PAGE_OFFSET (0x10000000) which mean a virtual address didn't
get translated to a physical address before real-mode code tried to
access it.
General Registers as specified by ABI
- FPU Registers must not be used in kernel mode
-
Control Registers
CR 0 (Recovery Counter) used for ptrace
CR 8 (Protection ID) per-process value*
CR 9, 12, 13 (PIDS) unused
CR10 (CCR) lazy FPU saving*
-CR11 as specified by ABI
+CR11 as specified by ABI (SAR)
CR14 (interruption vector) initialized to fault_vector
CR15 (EIEM) initialized to all ones*
CR16 (Interval Timer) read for cycle count/write starts Interval Tmr
CR17-CR22 interruption parameters
+CR19 Interrupt Instruction Register
+CR20 Interrupt Space Register
+CR21 Interrupt Offset Register
+CR22 Interrupt PSW
CR23 (EIRR) read for pending interrupts/write clears bits
CR24 (TR 0) Kernel Space Page Directory Pointer
CR25 (TR 1) User Space Page Directory Pointer
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 7
+SUBLEVEL = 8
EXTRAVERSION = -prep
NAME=Zonked Quokka
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# Select various configuration options depending on the machine type
config DISCONTIGMEM
bool
- depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_SROMLL)
+ depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
default y
help
Say Y to support efficient handling of discontiguous physical memory,
tune-$(CONFIG_CPU_V6) :=-mtune=strongarm
# Need -Uarm for gcc < 3.x
-CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Wa,-mno-fpu -Uarm
+CFLAGS +=-mapcs-32 $(arch-y) $(tune-y) $(call check_gcc,-malignment-traps,-mshort-load-bytes) -msoft-float -Wa,-mno-fpu -Uarm
AFLAGS +=-mapcs-32 $(arch-y) $(tune-y) -msoft-float -Wa,-mno-fpu
CHECK := $(CHECK) -D__arm__=1
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
# CONFIG_CPU_IS_SLOW is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_ECONET_AUNUDP is not set
# CONFIG_ECONET_NATIVE is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# Object file lists.
-obj-y := fiq.o time.o
-# generic.o
+obj-y := time.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
-obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a400.o
-obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a404.o
+obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o irq-lh7a400.o
+obj-$(CONFIG_MACH_LPD7A404) += arch-lpd7a40x.o irq-lh7a404.o
obj-m :=
obj-n :=
#ifdef CONFIG_MACH_LPD7A400
extern void lh7a400_init_irq (void);
+extern void lh7a40x_init_time (void);
MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
MAINTAINER ("Marc Singer")
BOOT_PARAMS (0xc0000100)
MAPIO (lpd7a400_map_io)
INITIRQ (lh7a400_init_irq)
+ INITTIME (lh7a40x_init_time)
INIT_MACHINE (lpd7a40x_init)
MACHINE_END
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
}
-static char softirq_stack[NR_CPUS * THREAD_SIZE] __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
-static char hardirq_stack[NR_CPUS * THREAD_SIZE] __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
+/*
+ * These should really be __section__(".bss.page_aligned") as well, but
+ * gcc's 3.0 and earlier don't handle that correctly.
+ */
+static char softirq_stack[NR_CPUS * THREAD_SIZE] __attribute__((__aligned__(THREAD_SIZE)));
+static char hardirq_stack[NR_CPUS * THREAD_SIZE] __attribute__((__aligned__(THREAD_SIZE)));
/*
* allocate per-cpu stacks for hardirq and for softirq processing
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
If you don't know what to do here, say N.
+config HOTPLUG_CPU
+ bool
+ default y if SMP
+ select HOTPLUG
+
+config DISCONTIGMEM
+ bool "Discontiguous memory support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Say Y to support efficient handling of discontiguous physical memory,
+ for architectures which are either NUMA (Non-Uniform Memory Access)
+ or have huge holes in the physical address space for other reasons.
+ See <file:Documentation/vm/numa> for more.
+
config PREEMPT
bool
# bool "Preemptible Kernel"
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does.
+config DEBUG_SPINLOCK
+ bool "Spinlock debugging"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here and build SMP to catch missing spinlock initialization
+ and certain other kinds of spinlock errors commonly made. This is
+ best used in conjunction with the NMI watchdog so that spinlock
+ deadlocks are also debuggable.
+
+config DEBUG_RWLOCK
+ bool "Read-write spinlock debugging"
+ depends on DEBUG_KERNEL && SMP
+ help
+ If you say Y here then read-write lock processing will count how many
+ times it has tried to get the lock and issue an error message after
+ too many attempts. If you suspect a rwlock problem or a kernel
+ hacker asks for this option then say Y. Otherwise say N.
+
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
help
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
# CONFIG_PA7000 is not set
# CONFIG_PA7100LC is not set
# CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
CONFIG_PA8X00=y
CONFIG_PA20=y
+CONFIG_PREFETCH=y
CONFIG_PARISC64=y
CONFIG_64BIT=y
-# CONFIG_PDC_NARROW is not set
# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
CONFIG_COMPAT=y
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
# CONFIG_SUPERIO is not set
-CONFIG_CHASSIS_LCD_LED=y
-# CONFIG_PDC_CHASSIS is not set
+# CONFIG_CHASSIS_LCD_LED is not set
+CONFIG_PDC_CHASSIS=y
#
# PCMCIA/CardBus support
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=m
#
# SCSI low-level drivers
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_IOMAPPED=y
+# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
#
# CONFIG_PCMCIA_FDOMAIN is not set
# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
#
# Multi-device support (RAID and LVM)
#
# I2O device support
#
+# CONFIG_I2O is not set
#
# Networking support
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_IP_NF_ARP_MANGLE=m
# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_RAW=m
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
CONFIG_LLC=m
CONFIG_LLC2=m
# CONFIG_IPX is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# Network testing
#
CONFIG_NET_PKTGEN=m
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
# CONFIG_ETHERTAP is not set
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_8139_RXBUF_IDX=1
# CONFIG_SIS900 is not set
CONFIG_EPIC100=m
# CONFIG_SUNDANCE is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
CONFIG_TIGON3=m
#
CONFIG_IXGB=m
CONFIG_IXGB_NAPI=y
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
+CONFIG_S2IO=m
+CONFIG_S2IO_NAPI=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
# CONFIG_PRISM54 is not set
CONFIG_NET_WIRELESS=y
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
#
# PCMCIA network device support
#
# CONFIG_PCMCIA_AXNET is not set
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
+# Wan interfaces
#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ISDN subsystem
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
CONFIG_CIFS=m
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
# CONFIG_CRYPTO_ARC4 is not set
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
#
# Library routines
#
CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=15
# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
# Processor type and features
#
# CONFIG_PA7000 is not set
-# CONFIG_PA7100LC is not set
-CONFIG_PA7200=y
+CONFIG_PA7100LC=y
+# CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
# CONFIG_64BIT is not set
CONFIG_PCI_NAMES=y
CONFIG_GSC_DINO=y
# CONFIG_PCI_LBA is not set
-# CONFIG_CHASSIS_LCD_LED is not set
+CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
#
#
# Generic Driver Options
#
+CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_DEBUG_DRIVER=y
#
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=y
# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_CARMEL=y
+# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# SCSI low-level drivers
#
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_ZALON is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
#
# Ethernet (10 or 100Mbit)
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
-# CONFIG_FDDI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_SLIP is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
#
# Wireless LAN (non-hamradio)
#
CONFIG_NET_WIRELESS=y
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-
#
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_FILTER is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
#
# ISDN subsystem
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
# CONFIG_INPUT_UINPUT is not set
# CONFIG_HP_SDC_RTC is not set
#
# CONFIG_I2C is not set
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
#
# Misc devices
#
# Graphics support
#
CONFIG_FB=y
+# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_STI=y
# CONFIG_FB_RIVA is not set
CONFIG_DUMMY_CONSOLE_ROWS=64
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_PCI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
# Miscellaneous filesystems
#
# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_NFS_V3=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+CONFIG_NFSD_TCP=y
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_TEST is not set
#
# Library routines
#
+# CONFIG_CRC_CCITT is not set
CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
CONFIG_LOG_BUF_SHIFT=16
CONFIG_HOTPLUG=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
#
# CONFIG_PA7000 is not set
# CONFIG_PA7100LC is not set
# CONFIG_PA7200 is not set
+# CONFIG_PA7300LC is not set
CONFIG_PA8X00=y
CONFIG_PA20=y
+CONFIG_PREFETCH=y
# CONFIG_PARISC64 is not set
# CONFIG_64BIT is not set
# CONFIG_SMP is not set
CONFIG_IOSAPIC=y
CONFIG_IOMMU_SBA=y
CONFIG_SUPERIO=y
-# CONFIG_CHASSIS_LCD_LED is not set
+CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
#
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_IDEDMA_AUTO is not set
# SCSI Transport Attributes
#
CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
+CONFIG_SCSI_FC_ATTRS=m
#
# SCSI low-level drivers
# CONFIG_SCSI_SATA_SVW is not set
CONFIG_SCSI_ATA_PIIX=m
CONFIG_SCSI_SATA_PROMISE=m
+# CONFIG_SCSI_SATA_SX4 is not set
CONFIG_SCSI_SATA_SIL=m
+# CONFIG_SCSI_SATA_SIS is not set
CONFIG_SCSI_SATA_VIA=m
# CONFIG_SCSI_SATA_VITESSE is not set
# CONFIG_SCSI_BUSLOGIC is not set
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_PCMCIA_FDOMAIN is not set
# CONFIG_PCMCIA_NINJA_SCSI is not set
CONFIG_PCMCIA_QLOGIC=m
+# CONFIG_PCMCIA_SYM53C500 is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_IP_NF_ARP_MANGLE=m
CONFIG_IP_NF_COMPAT_IPCHAINS=m
CONFIG_IP_NF_COMPAT_IPFWADM=m
+# CONFIG_IP_NF_RAW is not set
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
#
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
CONFIG_LLC=m
CONFIG_LLC2=m
# CONFIG_IPX is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
# CONFIG_ETHERTAP is not set
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
# CONFIG_8139_OLD_RX_RESET is not set
-CONFIG_8139_RXBUF_IDX=1
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
# CONFIG_SK98LIN is not set
CONFIG_TIGON3=m
#
CONFIG_IXGB=y
CONFIG_IXGB_NAPI=y
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
+# CONFIG_S2IO is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
#
-# Wan interfaces
+# Wireless LAN (non-hamradio)
#
-# CONFIG_WAN is not set
+# CONFIG_NET_RADIO is not set
#
# PCMCIA network device support
CONFIG_PCMCIA_AXNET=m
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
+# Wan interfaces
#
-# CONFIG_BT is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
#
# ISDN subsystem
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_STI=y
# CONFIG_FB_RIVA is not set
CONFIG_USB_KBTAB=m
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
CONFIG_USB_LEGOTOWER=m
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_TEST is not set
#
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set
#
# CONFIG_CRYPTO_ARC4 is not set
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_TEST=m
#
# Library routines
#
CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SLAB is not set
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_RWLOCK is not set
CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_INFO is not set
{
struct page *page = pte_page(pte);
- if (VALID_PAGE(page) && page_mapping(page) &&
+ if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
test_bit(PG_dcache_dirty, &page->flags)) {
flush_kernel_dcache_page(page_address(page));
{
seq_printf(m, "I-cache\t\t: %ld KB\n",
cache_info.ic_size/1024 );
- seq_printf(m, "D-cache\t\t: %ld KB (%s)%s\n",
+ seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n",
cache_info.dc_size/1024,
(cache_info.dc_conf.cc_wt ? "WT":"WB"),
- (cache_info.dc_conf.cc_sh ? " - shared I/D":"")
+ (cache_info.dc_conf.cc_sh ? ", shared I/D":""),
+ (cache_info.dc_conf.cc_assoc)
);
seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n",
panic("parisc_cache_init: pdc_cache_info failed");
#if 0
- printk(KERN_DEBUG "ic_size %lx dc_size %lx it_size %lx pdc_cache_info %d*long pdc_cache_cf %d\n",
- cache_info.ic_size,
- cache_info.dc_size,
- cache_info.it_size,
- sizeof (struct pdc_cache_info) / sizeof (long),
- sizeof (struct pdc_cache_cf)
- );
-
- printk(KERN_DEBUG "dc base %x dc stride %x dc count %x dc loop %d\n",
- cache_info.dc_base,
- cache_info.dc_stride,
- cache_info.dc_count,
- cache_info.dc_loop);
-
- printk(KERN_DEBUG "dc conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
- cache_info.dc_conf.cc_alias,
- cache_info.dc_conf.cc_block,
- cache_info.dc_conf.cc_line,
- cache_info.dc_conf.cc_wt,
- cache_info.dc_conf.cc_sh,
- cache_info.dc_conf.cc_cst,
- cache_info.dc_conf.cc_assoc);
-
- printk(KERN_DEBUG "ic conf: alias %d block %d line %d wt %d sh %d cst %d assoc %d\n",
- cache_info.ic_conf.cc_alias,
- cache_info.ic_conf.cc_block,
- cache_info.ic_conf.cc_line,
- cache_info.ic_conf.cc_wt,
- cache_info.ic_conf.cc_sh,
- cache_info.ic_conf.cc_cst,
- cache_info.ic_conf.cc_assoc);
-
- printk(KERN_DEBUG "dt conf: sh %d page %d cst %d aid %d pad1 %d \n",
- cache_info.dt_conf.tc_sh,
- cache_info.dt_conf.tc_page,
- cache_info.dt_conf.tc_cst,
- cache_info.dt_conf.tc_aid,
- cache_info.dt_conf.tc_pad1);
-
- printk(KERN_DEBUG "it conf: sh %d page %d cst %d aid %d pad1 %d \n",
- cache_info.it_conf.tc_sh,
- cache_info.it_conf.tc_page,
- cache_info.it_conf.tc_cst,
- cache_info.it_conf.tc_aid,
- cache_info.it_conf.tc_pad1);
+ printk("ic_size %lx dc_size %lx it_size %lx\n",
+ cache_info.ic_size,
+ cache_info.dc_size,
+ cache_info.it_size);
+
+ printk("DC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+ cache_info.dc_base,
+ cache_info.dc_stride,
+ cache_info.dc_count,
+ cache_info.dc_loop);
+
+ printk("dc_conf = 0x%lx alias %d blk %d line %d shift %d\n",
+ *(unsigned long *) (&cache_info.dc_conf),
+ cache_info.dc_conf.cc_alias,
+ cache_info.dc_conf.cc_block,
+ cache_info.dc_conf.cc_line,
+ cache_info.dc_conf.cc_shift);
+ printk(" wt %d sh %d cst %d assoc %d\n",
+ cache_info.dc_conf.cc_wt,
+ cache_info.dc_conf.cc_sh,
+ cache_info.dc_conf.cc_cst,
+ cache_info.dc_conf.cc_assoc);
+
+ printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n",
+ cache_info.ic_base,
+ cache_info.ic_stride,
+ cache_info.ic_count,
+ cache_info.ic_loop);
+
+ printk("ic_conf = 0x%lx alias %d blk %d line %d shift %d\n",
+ *(unsigned long *) (&cache_info.ic_conf),
+ cache_info.ic_conf.cc_alias,
+ cache_info.ic_conf.cc_block,
+ cache_info.ic_conf.cc_line,
+ cache_info.ic_conf.cc_shift);
+ printk(" wt %d sh %d cst %d assoc %d\n",
+ cache_info.ic_conf.cc_wt,
+ cache_info.ic_conf.cc_sh,
+ cache_info.ic_conf.cc_cst,
+ cache_info.ic_conf.cc_assoc);
+
+ printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+ cache_info.dt_conf.tc_sh,
+ cache_info.dt_conf.tc_page,
+ cache_info.dt_conf.tc_cst,
+ cache_info.dt_conf.tc_aid,
+ cache_info.dt_conf.tc_pad1);
+
+ printk("I-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n",
+ cache_info.it_conf.tc_sh,
+ cache_info.it_conf.tc_page,
+ cache_info.it_conf.tc_cst,
+ cache_info.it_conf.tc_aid,
+ cache_info.it_conf.tc_pad1);
#endif
split_tlb = 0;
split_tlb = 1;
}
- dcache_stride = (1 << (cache_info.dc_conf.cc_block + 3)) *
- cache_info.dc_conf.cc_line;
- icache_stride = (1 << (cache_info.ic_conf.cc_block + 3)) *
- cache_info.ic_conf.cc_line;
+ /* "New and Improved" version from Jim Hull
+ * (1 << (cc_block-1)) * (cc_line << (4 + cnf.cc_shift))
+ */
+#define CAFL_STRIDE(cnf) (cnf.cc_line << (3 + cnf.cc_block + cnf.cc_shift))
+ dcache_stride = CAFL_STRIDE(cache_info.dc_conf);
+ icache_stride = CAFL_STRIDE(cache_info.ic_conf);
+#undef CAFL_STRIDE
+
#ifndef CONFIG_PA20
if (pdc_btlb_info(&btlb_info) < 0) {
memset(&btlb_info, 0, sizeof btlb_info);
if ((boot_cpu_data.pdc.capabilities & PDC_MODEL_NVA_MASK) ==
PDC_MODEL_NVA_UNSUPPORTED) {
- printk(KERN_WARNING "Only equivalent aliasing supported\n");
-#ifndef CONFIG_SMP
+ printk(KERN_WARNING "parisc_cache_init: Only equivalent aliasing supported!\n");
+#if 0
panic("SMP kernel required to avoid non-equivalent aliasing");
#endif
}
disable_sr_hashing_asm(srhash_type);
}
-void __flush_dcache_page(struct page *page)
+void flush_dcache_page(struct page *page)
{
struct address_space *mapping = page_mapping(page);
struct vm_area_struct *mpnt = NULL;
unsigned long offset;
unsigned long addr;
pgoff_t pgoff;
+ pte_t *pte;
+ unsigned long pfn = page_to_pfn(page);
+
+
+ if (mapping && !mapping_mapped(mapping)) {
+ set_bit(PG_dcache_dirty, &page->flags);
+ return;
+ }
flush_kernel_dcache_page(page_address(page));
* isn't there, there's no point exciting the
* nadtlb handler into a nullification frenzy */
- if (!translation_exists(mpnt, addr))
+
+ if(!(pte = translation_exists(mpnt, addr)))
continue;
+ /* make sure we really have this page: the private
+ * mappings may cover this area but have COW'd this
+ * particular page */
+ if(pte_pfn(*pte) != pfn)
+ continue;
+
__flush_cache_page(mpnt, addr);
break;
}
flush_dcache_mmap_unlock(mapping);
}
-EXPORT_SYMBOL(__flush_dcache_page);
+EXPORT_SYMBOL(flush_dcache_page);
/* Defined in arch/parisc/kernel/pacache.S */
EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
/* Look up a PTE in a 2-Level scheme (faulting at each
* level if the entry isn't present
*
- * NOTE: we use ldw even for LP64 because our pte
- * and pmd are allocated <4GB */
+ * NOTE: we use ldw even for LP64, since the short pointers
+ * can address up to 1TB
+ */
.macro L2_ptep pmd,pte,index,va,fault
#if PT_NLEVELS == 3
EXTR \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
#else
EXTR \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
#endif
- DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
+ DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
copy %r0,\pte
ldw,s \index(\pmd),\pmd
+ bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
+ DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
+ copy \pmd,%r9
+#ifdef __LP64__
+ shld %r9,PxD_VALUE_SHIFT,\pmd
+#else
+ shlw %r9,PxD_VALUE_SHIFT,\pmd
+#endif
EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
- bb,>=,n \pmd,_PAGE_PRESENT_BIT,\fault
- DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
+ DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
LDREG %r0(\pmd),\pte /* pmd is now pte */
bb,>=,n \pte,_PAGE_PRESENT_BIT,\fault
copy %r0,\pte
extrd,u,*= \va,31,32,%r0
ldw,s \index(\pgd),\pgd
+ extrd,u,*= \va,31,32,%r0
+ bb,>=,n \pgd,_PxD_PRESENT_BIT,\fault
+ extrd,u,*= \va,31,32,%r0
+ shld \pgd,PxD_VALUE_SHIFT,\index
+ extrd,u,*= \va,31,32,%r0
+ copy \index,\pgd
extrd,u,*<> \va,31,32,%r0
ldo ASM_PGD_PMD_OFFSET(\pgd),\pgd
- extrd,u,*= \va,31,32,%r0
- bb,>=,n \pgd,_PAGE_PRESENT_BIT,\fault
L2_ptep \pgd,\pte,\index,\va,\fault
.endm
/* Set the dirty bit (and accessed bit). No need to be
* clever, this is only used from the dirty fault */
- .macro update_dirty ptep,pte,tmp,tmp1
+ .macro update_dirty ptep,pte,tmp
ldi _PAGE_ACCESSED|_PAGE_DIRTY,\tmp
or \tmp,\pte,\pte
STREG \pte,0(\ptep)
ret_from_kernel_thread:
/* Call schedule_tail first though */
- bl schedule_tail, %r2
+ BL schedule_tail, %r2
nop
LDREG TI_TASK-THREAD_SZ_ALGN(%r30), %r1
and %r9,%r16,%r17
cmpb,<>,n %r16,%r17,nadtlb_fault /* Not fdc,fic,pdc */
bb,>=,n %r9,26,nadtlb_nullify /* m bit not set, just nullify */
- b,l get_register,%r25
+ BL get_register,%r25
extrw,u %r9,15,5,%r8 /* Get index register # */
CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */
copy %r1,%r24
- b,l get_register,%r25
+ BL get_register,%r25
extrw,u %r9,10,5,%r8 /* Get base register # */
CMPIB=,n -1,%r1,nadtlb_fault /* have to use slow path */
- b,l set_register,%r25
+ BL set_register,%r25
add,l %r1,%r24,%r1 /* doesn't affect c/b bits */
nadtlb_nullify:
dbit_nolock_20w:
#endif
- update_dirty ptp,pte,t0,t1
+ update_dirty ptp,pte,t1
make_insert_tlb spc,pte,prot
dbit_nolock_11:
#endif
- update_dirty ptp,pte,t0,t1
+ update_dirty ptp,pte,t1
make_insert_tlb_11 spc,pte,prot
dbit_nolock_20:
#endif
- update_dirty ptp,pte,t0,t1
+ update_dirty ptp,pte,t1
make_insert_tlb spc,pte,prot
- f_extend pte,t0
+ f_extend pte,t1
idtlbt pte,prot
#include <asm/page.h>
#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#include <asm/system.h>
#include <asm/processor.h> /* for boot_cpu_data */
*/
void pdc_emergency_unlock(void)
{
- spin_unlock(&pdc_lock);
+ /* Spinlock DEBUG code freaks out if we unconditionally unlock */
+ if (spin_is_locked(&pdc_lock))
+ spin_unlock(&pdc_lock);
}
#ifdef __LP64__
int pdc_pat_chassis_send_log(unsigned long state, unsigned long data)
{
+ int retval = 0;
+
if (!is_pdc_pat())
return -1;
- int retval = 0;
-
spin_lock_irq(&pdc_lock);
retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data));
spin_unlock_irq(&pdc_lock);
return retval;
}
+
+/**
+ * pdc_pat_io_pci_cfg_read - Read PCI configuration space.
+ * @pci_addr: PCI configuration space address for which the read request is being made.
+ * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4.
+ * @mem_addr: Pointer to return memory buffer.
+ *
+ */
+int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr)
+{
+ int retval;
+ spin_lock_irq(&pdc_lock);
+ retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ,
+ __pa(pdc_result), pci_addr, pci_size);
+ switch(pci_size) {
+ case 1: *(u8 *) mem_addr = (u8) pdc_result[0];
+ case 2: *(u16 *)mem_addr = (u16) pdc_result[0];
+ case 4: *(u32 *)mem_addr = (u32) pdc_result[0];
+ }
+ spin_unlock_irq(&pdc_lock);
+
+ return retval;
+}
+
+/**
+ * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges.
+ * @pci_addr: PCI configuration space address for which the write request is being made.
+ * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4.
+ * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be
+ * written to PCI Config space.
+ *
+ */
+int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val)
+{
+ int retval;
+
+ spin_lock_irq(&pdc_lock);
+ retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE,
+ pci_addr, pci_size, val);
+ spin_unlock_irq(&pdc_lock);
+
+ return retval;
+}
#endif /* __LP64__ */
long real64_call(unsigned long fn, ...)
{
va_list args;
- extern struct wide_stack real_stack;
+ extern struct wide_stack real64_stack __attribute__ ((alias ("real_stack")));
extern unsigned long real64_call_asm(unsigned long *,
unsigned long *,
unsigned long);
va_start(args, fn);
- real_stack.arg0 = va_arg(args, unsigned long);
- real_stack.arg1 = va_arg(args, unsigned long);
- real_stack.arg2 = va_arg(args, unsigned long);
- real_stack.arg3 = va_arg(args, unsigned long);
- real_stack.arg4 = va_arg(args, unsigned long);
- real_stack.arg5 = va_arg(args, unsigned long);
- real_stack.arg6 = va_arg(args, unsigned long);
- real_stack.arg7 = va_arg(args, unsigned long);
- real_stack.arg8 = va_arg(args, unsigned long);
- real_stack.arg9 = va_arg(args, unsigned long);
- real_stack.arg10 = va_arg(args, unsigned long);
- real_stack.arg11 = va_arg(args, unsigned long);
- real_stack.arg12 = va_arg(args, unsigned long);
- real_stack.arg13 = va_arg(args, unsigned long);
+ real64_stack.arg0 = va_arg(args, unsigned long);
+ real64_stack.arg1 = va_arg(args, unsigned long);
+ real64_stack.arg2 = va_arg(args, unsigned long);
+ real64_stack.arg3 = va_arg(args, unsigned long);
+ real64_stack.arg4 = va_arg(args, unsigned long);
+ real64_stack.arg5 = va_arg(args, unsigned long);
+ real64_stack.arg6 = va_arg(args, unsigned long);
+ real64_stack.arg7 = va_arg(args, unsigned long);
+ real64_stack.arg8 = va_arg(args, unsigned long);
+ real64_stack.arg9 = va_arg(args, unsigned long);
+ real64_stack.arg10 = va_arg(args, unsigned long);
+ real64_stack.arg11 = va_arg(args, unsigned long);
+ real64_stack.arg12 = va_arg(args, unsigned long);
+ real64_stack.arg13 = va_arg(args, unsigned long);
va_end(args);
- return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn);
+ return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn);
}
#endif /* __LP64__ */
{HPHW_NPROC,0x67E,0x4,0x81,"Hitachi Tiny 80"},
{HPHW_NPROC,0x67F,0x4,0x81,"Hitachi Tiny 64"},
{HPHW_NPROC,0x700,0x4,0x91,"NEC Aska Processor"},
+ {HPHW_NPROC,0x880,0x4,0x91,"Orca Mako"},
+ {HPHW_NPROC,0x881,0x4,0x91,"Everest Mako"},
+ {HPHW_NPROC,0x882,0x4,0x91,"Rainier/Medel Mako Slow"},
+ {HPHW_NPROC,0x883,0x4,0x91,"Rainier/Medel Mako Fast"},
+ {HPHW_NPROC,0x884,0x4,0x91,"Mt. Hamilton"},
+ {HPHW_NPROC,0x885,0x4,0x91,"Mt. Hamilton DC-"},
+ {HPHW_NPROC,0x886,0x4,0x91,"Storm Peak Slow DC-"},
+ {HPHW_NPROC,0x887,0x4,0x91,"Storm Peak Slow"},
+ {HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"},
+ {HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"},
+ {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak"},
{HPHW_A_DIRECT, 0x004, 0x0000D, 0x00, "Arrakis MUX"},
{HPHW_A_DIRECT, 0x005, 0x0000D, 0x00, "Dyun Kiuh MUX"},
{HPHW_A_DIRECT, 0x006, 0x0000D, 0x00, "Baat Kiuh AP/MUX (40299B)"},
{HPHW_BCPORT, 0x800, 0x0000C, 0x10, "DEW BC Merced Port"},
{HPHW_BCPORT, 0x801, 0x0000C, 0x10, "SMC Bus Interface Merced Bus0"},
{HPHW_BCPORT, 0x802, 0x0000C, 0x10, "SMC Bus INterface Merced Bus1"},
- {HPHW_BCPORT, 0x803, 0x0000C, 0x10, "IKE I/O Bus Converter Merced Port"},
- {HPHW_BCPORT, 0x781, 0x0000C, 0x00, "IKE I/O Bus Converter Ropes Port"},
- {HPHW_BCPORT, 0x804, 0x0000C, 0x10, "REO I/O Bus Converter Merced Port"},
- {HPHW_BCPORT, 0x782, 0x0000C, 0x00, "REO I/O Bus Converter Ropes Port"},
+ {HPHW_BCPORT, 0x803, 0x0000C, 0x10, "IKE I/O BC Merced Port"},
+ {HPHW_BCPORT, 0x781, 0x0000C, 0x00, "IKE I/O BC Ropes Port"},
+ {HPHW_BCPORT, 0x804, 0x0000C, 0x10, "REO I/O BC Merced Port"},
+ {HPHW_BCPORT, 0x782, 0x0000C, 0x00, "REO I/O BC Ropes Port"},
+ {HPHW_BCPORT, 0x784, 0x0000C, 0x00, "Pluto I/O BC Ropes Port"},
{HPHW_BRIDGE, 0x680, 0x0000A, 0x00, "Dino PCI Bridge"},
{HPHW_BRIDGE, 0x682, 0x0000A, 0x00, "Cujo PCI Bridge"},
{HPHW_BRIDGE, 0x782, 0x0000A, 0x00, "Elroy PCI Bridge"},
{HPHW_BRIDGE, 0x583, 0x000A5, 0x00, "Saga PCI Bridge"},
+ {HPHW_BRIDGE, 0x783, 0x0000A, 0x00, "Mercury PCI Bridge"},
+ {HPHW_BRIDGE, 0x784, 0x0000A, 0x00, "Quicksilver AGP Bridge"},
{HPHW_B_DMA, 0x004, 0x00018, 0x00, "Parallel I/O"},
{HPHW_B_DMA, 0x004, 0x00019, 0x00, "Parallel RDB"},
{HPHW_B_DMA, 0x004, 0x00020, 0x80, "MID_BUS PSI"},
{HPHW_IOA, 0x581, 0x0000B, 0x10, "Uturn-IOA BC Runway Port"},
{HPHW_IOA, 0x582, 0x0000B, 0x10, "Astro BC Runway Port"},
{HPHW_IOA, 0x700, 0x0000B, 0x00, "NEC-IOS BC System Bus Port"},
+ {HPHW_IOA, 0x880, 0x0000C, 0x10, "Pluto BC McKinley Port"},
{HPHW_MEMORY, 0x002, 0x00008, 0x00, "MID_BUS"},
{HPHW_MEMORY, 0x063, 0x00009, 0x00, "712/132 L2 Upgrade"},
{HPHW_MEMORY, 0x064, 0x00009, 0x00, "712/160 L2 Upgrade"},
{HPHW_MEMORY, 0x065, 0x00009, 0x00, "715/132 L2 Upgrade"},
{HPHW_MEMORY, 0x066, 0x00009, 0x00, "715/160 L2 Upgrade"},
+ {HPHW_MEMORY, 0x0AF, 0x00009, 0x00, "Everest Mako Memory"},
{HPHW_OTHER, 0x004, 0x00030, 0x00, "Master"},
{HPHW_OTHER, 0x004, 0x00034, 0x00, "Slave"},
{HPHW_OTHER, 0x004, 0x00038, 0x00, "EDU"},
{HPHW_OTHER, 0x004, 0x00049, 0x00, "LGB Control"},
+ {HPHW_MC, 0x004, 0x000C0, 0x00, "BMC IPMI Mgmt Ctlr"},
{HPHW_FAULTY, 0, } /* Special Marker for last entry */
};
[pcxw] { "PA8500 (PCX-W)", "2.0" },
[pcxw_] { "PA8600 (PCX-W+)", "2.0" },
[pcxw2] { "PA8700 (PCX-W2)", "2.0" },
- [mako] { "PA8800 (MAKO)", "2.0" }
+ [mako] { "PA8800 (Mako)", "2.0" }
};
const char * __init
/* Initialize startup VM. Just map first 8 MB of memory */
ldil L%PA(pg0),%r1
ldo R%PA(pg0)(%r1),%r1
- ldo _PAGE_TABLE(%r1),%r3
+ shr %r1,PxD_VALUE_SHIFT,%r3
+ ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
ldil L%PA(swapper_pg_dir),%r4
ldo R%PA(swapper_pg_dir)(%r4),%r4
ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
1:
stw %r3,0(%r4)
- ldo ASM_PAGE_SIZE(%r3),%r3
+ ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
addib,> -1,%r1,1b
ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
ldil L%PA(smp_init_current_idle_task),%sp
ldo R%PA(smp_init_current_idle_task)(%sp),%sp
ldw 0(%sp),%sp /* load task address */
+ tophys_r1 %sp
+ ldw TASK_THREAD_INFO(%sp), %sp
mtctl %sp,%cr30 /* store in cr30 */
addil L%THREAD_SZ_ALGN,%sp /* stack is above task */
ldo R%THREAD_SZ_ALGN(%r1),%sp
ldil L%PA(pmd0),%r5
ldo R%PA(pmd0)(%r5),%r5
- ldo _PAGE_TABLE(%r5),%r3
+ shrd %r5,PxD_VALUE_SHIFT,%r3
+ ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
ldil L%PA(swapper_pg_dir),%r4
ldo R%PA(swapper_pg_dir)(%r4),%r4
stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
- ldo _PAGE_TABLE(%r1),%r3
+ shrd %r1,PxD_VALUE_SHIFT,%r3
+ ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r5
ldi ASM_PT_INITIAL,%r1
1:
stw %r3,0(%r5)
- ldo ASM_PAGE_SIZE(%r3),%r3
+ ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
addib,> -1,%r1,1b
ldo ASM_PMD_ENTRY_SIZE(%r5),%r5
- ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
+ ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
ldil L%PA(pg0),%r1
ldo R%PA(pg0)(%r1),%r1
/* Initialize the SP - monarch sets up smp_init_current_idle_task */
load32 PA(smp_init_current_idle_task),%sp
ldd 0(%sp),%sp /* load task address */
+ tophys_r1 %sp
ldd TASK_THREAD_INFO(%sp), %sp
mtctl %sp,%cr30 /* store in cr30 */
ldo THREAD_SZ_ALGN(%sp),%sp
#include <linux/mm.h>
#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/mmzone.h>
#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/parisc-device.h>
#endif
};
-struct irq_region_ops cpu_irq_ops = {
- .disable_irq = disable_cpu_irq,
- .enable_irq = enable_cpu_irq,
- .mask_irq = unmask_cpu_irq,
- .unmask_irq = unmask_cpu_irq
-};
struct irq_region cpu0_irq_region = {
.ops = {
{
struct irq_region *region;
- DBG_IRQ(irq, ("enable_irq(%d) %d+%d eiem 0x%lx\n", irq,
- IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
+ DBG_IRQ(irq, ("enable_irq(%d) %d+%d EIRR 0x%lx EIEM 0x%lx\n", irq,
+ IRQ_REGION(irq), IRQ_OFFSET(irq), mfctl(23), mfctl(15)));
irq = irq_canonicalize(irq);
region = irq_region[IRQ_REGION(irq)];
seq_puts(p, " ");
#ifdef CONFIG_SMP
for (i = 0; i < NR_CPUS; i++)
+ if (cpu_online(i))
#endif
- seq_printf(p, " CPU%02d ", i);
+ seq_printf(p, " CPU%02d ", i);
#ifdef PARISC_IRQ_CR16_COUNTS
seq_printf(p, "[min/avg/max] (CPU cycle counts)");
seq_printf(p, "%3d: ", irq_no);
#ifdef CONFIG_SMP
for (; j < NR_CPUS; j++)
+ if (cpu_online(j))
#endif
seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq_no]);
next_cpu++; /* assign to "next" CPU we want this bugger on */
/* validate entry */
- while ((next_cpu < NR_CPUS) && !cpu_data[next_cpu].txn_addr)
+ while ((next_cpu < NR_CPUS) && (!cpu_data[next_cpu].txn_addr ||
+ !cpu_online(next_cpu)))
next_cpu++;
if (next_cpu >= NR_CPUS)
irq_enter();
++kstat_cpu(cpu).irqs[irq];
- DBG_IRQ(irq, ("do_irq(%d) %d+%d\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq)));
+ DBG_IRQ(irq, ("do_irq(%d) %d+%d eiem 0x%lx\n", irq, IRQ_REGION(irq), IRQ_OFFSET(irq), cpu_eiem));
for (; action; action = action->next) {
#ifdef PARISC_IRQ_CR16_COUNTS
#ifdef DEBUG_IRQ
if (eirr_val != (1UL << MAX_CPU_IRQ))
- printk(KERN_DEBUG "do_cpu_irq_mask %x\n", eirr_val);
+ printk(KERN_DEBUG "do_cpu_irq_mask 0x%x & 0x%x\n", eirr_val, cpu_eiem);
#endif
/* Work our way from MSb to LSb...same order we alloc EIRs */
void __init init_IRQ(void)
{
local_irq_disable(); /* PARANOID - should already be disabled */
- mtctl(-1L, 23); /* EIRR : clear all pending external intr */
+ mtctl(~0UL, 23); /* EIRR : clear all pending external intr */
#ifdef CONFIG_SMP
if (!cpu_eiem)
cpu_eiem = EIEM_MASK(IPI_IRQ) | EIEM_MASK(TIMER_IRQ);
extern void $$dyncall(void);
EXPORT_SYMBOL($$dyncall);
#endif
+
+#ifdef CONFIG_DISCONTIGMEM
+#include <asm/mmzone.h>
+EXPORT_SYMBOL(node_data);
+EXPORT_SYMBOL(pfnnid_map);
+#endif
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
+#ifdef DEBUG_PCI
+#undef ASSERT
+#define ASSERT(expr) \
+ if(!(expr)) { \
+ printk("\n%s:%d: Assertion " #expr " failed!\n", \
+ __FILE__, __LINE__); \
+ panic(#expr); \
+ }
+#else
+#define ASSERT(expr)
+#endif
+
+
static struct proc_dir_entry * proc_gsc_root = NULL;
static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
static unsigned long pcxl_used_bytes = 0;
* interfaces to log Chassis Codes via PDC (firmware)
*
* Copyright (C) 2002 Laurent Canet <canetl@esiee.fr>
- * Copyright (C) 2002-2003 Thibaut Varene <varenet@esiee.fr>
+ * Copyright (C) 2002-2004 Thibaut VARENE <varenet@esiee.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <asm/pdc_chassis.h>
#include <asm/processor.h>
+#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#ifdef CONFIG_PDC_CHASSIS
static int pdc_chassis_old = 0;
+static unsigned int pdc_chassis_enabled = 1;
+
+
+/**
+ * pdc_chassis_setup() - Enable/disable pdc_chassis code at boot time.
+ * @str configuration param: 0 to disable chassis log
+ * @return 1
+ */
+
+static int __init pdc_chassis_setup(char *str)
+{
+ /*panic_timeout = simple_strtoul(str, NULL, 0);*/
+ get_option(&str, &pdc_chassis_enabled);
+ return 1;
+}
+__setup("pdcchassis=", pdc_chassis_setup);
/**
{
#ifdef CONFIG_PDC_CHASSIS
int handle = 0;
+ if (pdc_chassis_enabled) {
+ DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
+
+ /* Let see if we have something to handle... */
+ /* Check for PDC_PAT or old LED Panel */
+ pdc_chassis_checkold();
+ if (is_pdc_pat()) {
+ printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
+ handle = 1;
+ }
+ else if (pdc_chassis_old) {
+ printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
+ handle = 1;
+ }
- DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
-
- /* Let see if we have something to handle... */
- /* Check for PDC_PAT or old LED Panel */
- pdc_chassis_checkold();
- if (is_pdc_pat()) {
-#ifdef __LP64__ /* see pdc_chassis_send_status() */
- printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
- handle = 1;
-#endif /* __LP64__ */
- }
- else if (pdc_chassis_old) {
- printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
- handle = 1;
- }
-
- if (handle) {
- /* initialize panic notifier chain */
- notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block);
+ if (handle) {
+ /* initialize panic notifier chain */
+ notifier_chain_register(&panic_notifier_list, &pdc_chassis_panic_block);
- /* initialize reboot notifier chain */
- register_reboot_notifier(&pdc_chassis_reboot_block);
+ /* initialize reboot notifier chain */
+ register_reboot_notifier(&pdc_chassis_reboot_block);
+ }
}
#endif /* CONFIG_PDC_CHASSIS */
}
/* Maybe we should do that in an other way ? */
int retval = 0;
#ifdef CONFIG_PDC_CHASSIS
- DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
-
-#ifdef __LP64__ /* pdc_pat_chassis_send_log is defined only when #ifdef __LP64__ */
- if (is_pdc_pat()) {
- switch(message) {
- case PDC_CHASSIS_DIRECT_BSTART:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BSTART, PDC_CHASSIS_LSTATE_RUN_NORMAL);
- break;
-
- case PDC_CHASSIS_DIRECT_BCOMPLETE:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BCOMPLETE, PDC_CHASSIS_LSTATE_RUN_NORMAL);
- break;
-
- case PDC_CHASSIS_DIRECT_SHUTDOWN:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_SHUTDOWN, PDC_CHASSIS_LSTATE_NONOS);
- break;
-
- case PDC_CHASSIS_DIRECT_PANIC:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_PANIC, PDC_CHASSIS_LSTATE_RUN_CRASHREC);
- break;
-
- case PDC_CHASSIS_DIRECT_LPMC:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_LPMC, PDC_CHASSIS_LSTATE_RUN_SYSINT);
- break;
-
- case PDC_CHASSIS_DIRECT_HPMC:
- retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_HPMC, PDC_CHASSIS_LSTATE_RUN_NCRIT);
- break;
-
- default:
- retval = -1;
- }
- } else retval = -1;
+ if (pdc_chassis_enabled) {
+
+ DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
+
+#ifdef CONFIG_PARISC64
+ if (is_pdc_pat()) {
+ switch(message) {
+ case PDC_CHASSIS_DIRECT_BSTART:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BSTART, PDC_CHASSIS_LSTATE_RUN_NORMAL);
+ break;
+
+ case PDC_CHASSIS_DIRECT_BCOMPLETE:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_BCOMPLETE, PDC_CHASSIS_LSTATE_RUN_NORMAL);
+ break;
+
+ case PDC_CHASSIS_DIRECT_SHUTDOWN:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_SHUTDOWN, PDC_CHASSIS_LSTATE_NONOS);
+ break;
+
+ case PDC_CHASSIS_DIRECT_PANIC:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_PANIC, PDC_CHASSIS_LSTATE_RUN_CRASHREC);
+ break;
+
+ case PDC_CHASSIS_DIRECT_LPMC:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_LPMC, PDC_CHASSIS_LSTATE_RUN_SYSINT);
+ break;
+
+ case PDC_CHASSIS_DIRECT_HPMC:
+ retval = pdc_pat_chassis_send_log(PDC_CHASSIS_PMSG_HPMC, PDC_CHASSIS_LSTATE_RUN_NCRIT);
+ break;
+
+ default:
+ retval = -1;
+ }
+ } else retval = -1;
#else
- if (pdc_chassis_old) {
- switch (message) {
- case PDC_CHASSIS_DIRECT_BSTART:
- case PDC_CHASSIS_DIRECT_BCOMPLETE:
- retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
- break;
-
- case PDC_CHASSIS_DIRECT_SHUTDOWN:
- retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_SHUT));
- break;
-
- case PDC_CHASSIS_DIRECT_HPMC:
- case PDC_CHASSIS_DIRECT_PANIC:
- retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_FLT));
- break;
-
- case PDC_CHASSIS_DIRECT_LPMC:
- retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_WARN));
- break;
-
- default:
- retval = -1;
- }
- } else retval = -1;
-#endif /* __LP64__ */
+ if (pdc_chassis_old) {
+ switch (message) {
+ case PDC_CHASSIS_DIRECT_BSTART:
+ case PDC_CHASSIS_DIRECT_BCOMPLETE:
+ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN));
+ break;
+
+ case PDC_CHASSIS_DIRECT_SHUTDOWN:
+ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_SHUT));
+ break;
+
+ case PDC_CHASSIS_DIRECT_HPMC:
+ case PDC_CHASSIS_DIRECT_PANIC:
+ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_FLT));
+ break;
+
+ case PDC_CHASSIS_DIRECT_LPMC:
+ retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_WARN));
+ break;
+
+ default:
+ retval = -1;
+ }
+ } else retval = -1;
+#endif /* CONFIG_PARISC64 */
+ } /* if (pdc_chassis_enabled) */
#endif /* CONFIG_PDC_CHASSIS */
return retval;
}
/*
* These bracket the sleeping functions..
*/
-# define first_sched ((unsigned long) scheduling_functions_start_here)
-# define last_sched ((unsigned long) scheduling_functions_end_here)
unwind_frame_init_from_blocked_task(&info, p);
do {
if (unwind_once(&info) < 0)
return 0;
ip = info.ip;
- if (ip < first_sched || ip >= last_sched)
+ if (!in_sched_functions(ip))
return ip;
} while (count++ < 16);
return 0;
-# undef first_sched
-# undef last_sched
}
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
+#include <linux/cpu.h>
#include <asm/cache.h>
#include <asm/hardware.h> /* for register_parisc_driver() stuff */
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#include <asm/irq.h> /* for struct irq_region */
#include <asm/parisc-device.h>
cpu_irq_actions[cpuid] = actions;
}
#endif
+
+ /*
+ * Bring this CPU up now! (ignore bootstrap cpuid == 0)
+ */
+#ifdef CONFIG_SMP
+ if (cpuid) {
+ cpu_set(cpuid, cpu_present_map);
+ cpu_up(cpuid);
+ }
+#endif
+
return 0;
}
.section .bss
.export real_stack
+ .export real32_stack
+ .export real64_stack
.align 64
real_stack:
+real32_stack:
+real64_stack:
.block 8192
#ifdef __LP64__
/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
struct proc_dir_entry * proc_runway_root = NULL;
struct proc_dir_entry * proc_gsc_root = NULL;
+struct proc_dir_entry * proc_mckinley_root = NULL;
+
void __init setup_cmdline(char **cmdline_p)
{
case pcxw:
case pcxw_:
case pcxw2:
- case mako: /* XXX : this is really mckinley bus */
if (NULL == proc_runway_root)
{
proc_runway_root = proc_mkdir("bus/runway", 0);
}
break;
+ case mako:
+ if (NULL == proc_mckinley_root)
+ {
+ proc_mckinley_root = proc_mkdir("bus/mckinley", 0);
+ }
+ break;
default:
/* FIXME: this was added to prevent the compiler
* complaining about missing pcx, pcxs and pcxt
#define kDEBUG 0
-spinlock_t pa_dbit_lock = SPIN_LOCK_UNLOCKED;
-
spinlock_t smp_lock = SPIN_LOCK_UNLOCKED;
volatile struct task_struct *smp_init_current_idle_task;
static volatile int cpu_now_booting = 0; /* track which CPU is booting */
-static int parisc_max_cpus = -1; /* Command line */
unsigned long cache_decay_ticks; /* declared by include/linux/sched.h */
+
+static int parisc_max_cpus = 1;
+
+/* online cpus are ones that we've managed to bring up completely
+ * possible cpus are all valid cpu
+ * present cpus are all detected cpu
+ *
+ * On startup we bring up the "possible" cpus. Since we discover
+ * CPUs later, we add them as hotplug, so the possible cpu mask is
+ * empty in the beginning.
+ */
+
cpumask_t cpu_online_map = CPU_MASK_NONE; /* Bitmap of online CPUs */
-cpumask_t cpu_possible_map = CPU_MASK_NONE; /* Bitmap of Present CPUs */
+cpumask_t cpu_possible_map = CPU_MASK_ALL; /* Bitmap of Present CPUs */
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(cpu_possible_map);
{
int i;
- for (i = 0; i < parisc_max_cpus; i++) {
+ for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i) && i != smp_processor_id())
send_IPI_single(i, op);
}
unsigned long timeout;
static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ if (num_online_cpus() < 2)
+ return 0;
+
/* Can deadlock when called with interrupts disabled */
WARN_ON(irqs_disabled());
EXPORT_SYMBOL(smp_call_function);
-
-
-/*
- * Setup routine for controlling SMP activation
- *
- * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
- * activation entirely (the MPS table probe still happens, though).
- *
- * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
- * greater than 0, limits the maximum number of CPUs activated in
- * SMP mode to <NUM>.
- */
-
-static int __init nosmp(char *str)
-{
- parisc_max_cpus = 0;
- return 1;
-}
-
-__setup("nosmp", nosmp);
-
-static int __init maxcpus(char *str)
-{
- get_option(&str, &parisc_max_cpus);
- return 1;
-}
-
-__setup("maxcpus=", maxcpus);
-
/*
* Flush all other CPU's tlb and then mine. Do this with on_each_cpu()
* as we want to ensure all TLB's flushed before proceeding.
panic("smp_callin() AAAAaaaaahhhh....\n");
}
-#if 0
/*
* Create the idle task for a new Slave CPU. DO NOT use kernel_thread()
* because that could end up calling schedule(). If it did, the new idle
/*
* Bring one cpu online.
*/
-int __init smp_boot_one_cpu(int cpuid, int cpunum)
+int __init smp_boot_one_cpu(int cpuid)
{
struct task_struct *idle;
long timeout;
panic("SMP: fork failed for CPU:%d", cpuid);
wake_up_forked_process(idle);
- init_idle(idle, cpunum);
+ init_idle(idle, cpuid);
unhash_process(idle);
- idle->thread_info->cpu = cpunum;
+ idle->thread_info->cpu = cpuid;
/* Let _start know what logical CPU we're booting
** (offset into init_tasks[],cpu_data[])
*/
- cpu_now_booting = cpunum;
+ cpu_now_booting = cpuid;
/*
** boot strap code needs to know the task address since
smp_init_current_idle_task = idle ;
mb();
+ printk("Releasing cpu %d now, hpa=%lx\n", cpuid, cpu_data[cpuid].hpa);
+
/*
** This gets PDC to release the CPU from a very tight loop.
- ** See MEM_RENDEZ comments in head.S.
+ **
+ ** From the PA-RISC 2.0 Firmware Architecture Reference Specification:
+ ** "The MEM_RENDEZ vector specifies the location of OS_RENDEZ which
+ ** is executed after receiving the rendezvous signal (an interrupt to
+ ** EIR{0}). MEM_RENDEZ is valid only when it is nonzero and the
+ ** contents of memory are valid."
*/
- __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpunum].hpa);
+ __raw_writel(IRQ_OFFSET(TIMER_IRQ), cpu_data[cpuid].hpa);
mb();
/*
* Once the "monarch CPU" sees the bit change, it can move on.
*/
for (timeout = 0; timeout < 10000; timeout++) {
- if(cpu_online(cpunum)) {
+ if(cpu_online(cpuid)) {
/* Which implies Slave has started up */
cpu_now_booting = 0;
smp_init_current_idle_task = NULL;
alive:
/* Remember the Slave data */
#if (kDEBUG>=100)
- printk(KERN_DEBUG "SMP: CPU:%d (num %d) came alive after %ld _us\n",
- cpuid, cpunum, timeout * 100);
+ printk(KERN_DEBUG "SMP: CPU:%d came alive after %ld _us\n",
+ cpuid, timeout * 100);
#endif /* kDEBUG */
#ifdef ENTRY_SYS_CPUS
- cpu_data[cpunum].state = STATE_RUNNING;
+ cpu_data[cpuid].state = STATE_RUNNING;
#endif
return 0;
}
-#endif
-
void __devinit smp_prepare_boot_cpu(void)
{
#endif
/* Setup BSP mappings */
- printk(KERN_DEBUG "SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
- init_task.thread_info->cpu = bootstrap_processor;
- current->thread_info->cpu = bootstrap_processor;
+ printk("SMP: bootstrap CPU ID is %d\n",bootstrap_processor);
cpu_set(bootstrap_processor, cpu_online_map);
- cpu_set(bootstrap_processor, cpu_possible_map);
-
- /* Mark Boostrap processor as present */
- current->active_mm = &init_mm;
+ cpu_set(bootstrap_processor, cpu_present_map);
cache_decay_ticks = HZ/100; /* FIXME very rough. */
}
*/
void __init smp_prepare_cpus(unsigned int max_cpus)
{
+ cpus_clear(cpu_present_map);
+ cpu_set(0, cpu_present_map);
- if (max_cpus != -1)
- printk(KERN_INFO "SMP: Limited to %d CPUs\n", max_cpus);
-
- printk(KERN_INFO "SMP: Monarch CPU activated (%lu.%02lu BogoMIPS)\n",
- (cpu_data[0].loops_per_jiffy + 25) / 5000,
- ((cpu_data[0].loops_per_jiffy + 25) / 50) % 100);
-
- return;
+ parisc_max_cpus = max_cpus;
+ if (!max_cpus)
+ printk(KERN_INFO "SMP mode deactivated.\n");
}
int __devinit __cpu_up(unsigned int cpu)
{
+ if (cpu != 0 && cpu < parisc_max_cpus)
+ smp_boot_one_cpu(cpu);
+
return cpu_online(cpu) ? 0 : -ENOSYS;
}
asmlinkage long sys32_time(compat_time_t *tloc)
{
- struct timeval tv;
+ struct timeval tv;
+ compat_time_t now32;
do_gettimeofday(&tv);
- compat_time_t now32 = tv.tv_sec;
+ now32 = tv.tv_sec;
if (tloc)
if (put_user(now32, tloc))
put_user(reclen, &dirent->d_reclen);
copy_to_user(dirent->d_name, name, namlen);
put_user(0, dirent->d_name + namlen);
- ((char *) dirent) += reclen;
+ dirent = (struct linux32_dirent *)((char *)dirent + reclen);
buf->current_dir = dirent;
buf->count -= reclen;
return 0;
#include <asm/smp.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
+#include <asm/unwind.h>
#include "../math-emu/math-emu.h" /* for handle_fpe() */
#define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
/* dumped to the console via printk) */
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+spinlock_t pa_dbit_lock = SPIN_LOCK_UNLOCKED;
+#endif
+
int printbinary(char *buf, unsigned long x, int nbits)
{
unsigned long mask = 1UL << (nbits - 1);
void dump_stack(void)
{
- unsigned long stack;
- show_trace(current, &stack);
+ show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
-#ifndef __LP64__
-static int kstack_depth_to_print = 64 * 4;
-#else
-static int kstack_depth_to_print = 128 * 4;
-#endif
-
-void show_stack(struct task_struct *task, unsigned long *sp)
+void show_stack(struct task_struct *task, unsigned long *s)
{
- unsigned long *stack;
- int i;
-
- /*
- * debugging aid: "show_stack(NULL);" prints the
- * back trace for this cpu.
- */
- if (task==NULL)
- sp = (unsigned long*)&sp;
- else if(sp == NULL)
- sp = (unsigned long*)task->thread.regs.ksp;
-
- stack = sp;
- printk("\n" KERN_CRIT "Stack Dump:\n");
- printk(KERN_CRIT " " RFMT ": ", (unsigned long) stack);
- for (i=0; i < kstack_depth_to_print; i++) {
- if (((long) stack & (THREAD_SIZE-1)) == 0)
- break;
- if (i && ((i & 0x03) == 0))
- printk("\n" KERN_CRIT " " RFMT ": ",
- (unsigned long) stack);
- printk(RFMT " ", *stack--);
+ int i = 1;
+ struct unwind_frame_info info;
+
+ if (!task) {
+ unsigned long sp, ip, rp;
+
+HERE:
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+ ip = (unsigned long)&&HERE;
+ rp = (unsigned long)__builtin_return_address(0);
+ unwind_frame_init(&info, current, sp, ip, rp);
+ } else {
+ unwind_frame_init_from_blocked_task(&info, task);
}
- printk("\n" KERN_CRIT "\n");
- show_trace(task, sp);
-}
+ printk("Backtrace:\n");
+ while (i <= 16) {
+ if (unwind_once(&info) < 0 || info.ip == 0)
+ break;
-void show_trace(struct task_struct *task, unsigned long *stack)
-{
- unsigned long *startstack;
- unsigned long addr;
- int i;
-
- startstack = (unsigned long *)((unsigned long)stack & ~(THREAD_SIZE - 1));
- i = 1;
- stack = (long *)((long)(stack + 32) &~ (FRAME_SIZE-1)); /* Align */
- printk("Kernel addresses on the stack:\n");
- while (stack > startstack) {
- stack -= 16; /* Stack frames are a multiple of 16 words */
- addr = stack[16 - RP_OFFSET / sizeof(long)];
- /*
- * If the address is either in the text segment of the
- * kernel, or in the region which contains vmalloc'ed
- * memory, it *may* be the address of a calling
- * routine; if so, print it so that someone tracing
- * down the cause of the crash will be able to figure
- * out the call path that was taken.
- */
- if (__kernel_text_address(addr)) {
- printk(" [<" RFMT ">] ", addr);
+ if (__kernel_text_address(info.ip)) {
+ printk(" [<" RFMT ">] ", info.ip);
#ifdef CONFIG_KALLSYMS
- print_symbol("%s\n", addr);
+ print_symbol("%s\n", info.ip);
#else
if ((i & 0x03) == 0)
printk("\n");
* understand what is happening here
*/
-/*
- * J. David Anglin writes:
- *
- * "You have to adjust the current sp to that at the begining of the function.
- * There can be up to two stack additions to allocate the frame in the
- * prologue. Similar things happen in the epilogue. In the presence of
- * interrupts, you have to be concerned about where you are in the function
- * and what stack adjustments have taken place."
- *
- * For now these cases are not handled, but they should be!
- */
-
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#define dbg(x...)
#endif
-extern const struct unwind_table_entry __start___unwind[];
-extern const struct unwind_table_entry __stop___unwind[];
+extern struct unwind_table_entry __start___unwind[];
+extern struct unwind_table_entry __stop___unwind[];
static spinlock_t unwind_lock;
/*
const struct unwind_table_entry *e = 0;
unsigned long lo, hi, mid;
- addr -= table->base_addr;
-
for (lo = 0, hi = table->length; lo < hi; )
{
mid = (lo + hi) / 2;
static void
unwind_table_init(struct unwind_table *table, const char *name,
unsigned long base_addr, unsigned long gp,
- const void *table_start, const void *table_end)
+ void *table_start, void *table_end)
{
- const struct unwind_table_entry *start = table_start;
- const struct unwind_table_entry *end = table_end - 1;
+ struct unwind_table_entry *start = table_start;
+ struct unwind_table_entry *end =
+ (struct unwind_table_entry *)table_end - 1;
table->name = name;
table->base_addr = base_addr;
table->start = base_addr + start->region_start;
table->end = base_addr + end->region_end;
table->table = (struct unwind_table_entry *)table_start;
- table->length = end - start;
+ table->length = end - start + 1;
table->next = NULL;
+
+ for (; start <= end; start++) {
+ start->region_start += base_addr;
+ start->region_end += base_addr;
+ }
}
void *
unwind_table_add(const char *name, unsigned long base_addr,
unsigned long gp,
- const void *start, const void *end)
+ void *start, void *end)
{
struct unwind_table *table;
unsigned long flags;
sp = info->prev_sp;
} while (info->prev_ip < (unsigned long)_stext ||
info->prev_ip > (unsigned long)_etext);
+
+ dbg("analyzing func @ %lx with no unwind info, setting prev_sp=%lx prev_ip=%lx\n", info->ip, info->prev_sp, info->prev_ip);
} else {
dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, Save_RP = %d size = %u\n",
/* ldo X(sp), sp, or stwm X,D(sp) */
frame_size += (insn & 0x1 ? -1 << 13 : 0) |
((insn & 0x3fff) >> 1);
+ dbg("analyzing func @ %lx, insn=%08x @ %lx, frame_size = %ld\n", info->ip, insn, npc, frame_size);
} else if ((insn & 0xffe00008) == 0x7ec00008) {
/* std,ma X,D(sp) */
frame_size += (insn & 0x1 ? -1 << 13 : 0) |
(((insn >> 4) & 0x3ff) << 3);
+ dbg("analyzing func @ %lx, insn=%08x @ %lx, frame_size = %ld\n", info->ip, insn, npc, frame_size);
} else if (insn == 0x6bc23fd9) {
/* stw rp,-20(sp) */
rpoffset = 20;
looking_for_rp = 0;
+ dbg("analyzing func @ %lx, insn=stw rp,-20(sp) @ %lx\n", info->ip, npc);
} else if (insn == 0x0fc212c1) {
/* std rp,-16(sr0,sp) */
rpoffset = 16;
looking_for_rp = 0;
+ dbg("analyzing func @ %lx, insn=std rp,-16(sp) @ %lx\n", info->ip, npc);
}
}
info->prev_sp = info->sp - frame_size;
if (rpoffset)
- info->prev_ip = *(unsigned long *)(info->prev_sp - rpoffset);
+ info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
+ info->prev_ip = info->rp;
+ info->rp = 0;
+
+ dbg("analyzing func @ %lx, setting prev_sp=%lx prev_ip=%lx\n", info->ip, info->prev_sp, info->prev_ip);
}
}
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
- struct pt_regs *regs)
+ unsigned long sp, unsigned long ip, unsigned long rp)
{
memset(info, 0, sizeof(struct unwind_frame_info));
info->t = t;
- info->sp = regs->ksp;
- info->ip = regs->kpc;
+ info->sp = sp;
+ info->ip = ip;
+ info->rp = rp;
- dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n", (int)t->pid, info->sp, info->ip);
+ dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n", t ? (int)t->pid : 0, info->sp, info->ip);
}
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
{
struct pt_regs *regs = &t->thread.regs;
- unwind_frame_init(info, t, regs);
+ unwind_frame_init(info, t, regs->ksp, regs->kpc, 0);
+}
+
+void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
+{
+ unwind_frame_init(info, current, regs->gr[30], regs->iaoq[0],
+ regs->gr[2]);
}
int unwind_once(struct unwind_frame_info *next_frame)
#
lib-y := lusercopy.o bitops.o checksum.o io.o memset.o
+
+lib-$(CONFIG_SMP) += debuglocks.o
unsigned long __xchg32(int x, int *ptr)
{
unsigned long flags;
- unsigned long temp;
+ long temp;
atomic_spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
- (long) temp = (long) *ptr; /* XXX - sign extension wanted? */
+ temp = (long) *ptr; /* XXX - sign extension wanted? */
*ptr = x;
atomic_spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
- return temp;
+ return (unsigned long)temp;
}
unsigned long __xchg8(char x, char *ptr)
{
unsigned long flags;
- unsigned long temp;
+ long temp;
atomic_spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
- (long) temp = (long) *ptr; /* XXX - sign extension wanted? */
+ temp = (long) *ptr; /* XXX - sign extension wanted? */
*ptr = x;
atomic_spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
- return temp;
+ return (unsigned long)temp;
}
goto bytecopy;
while (dest & 3) {
writeb(*(char *)src, dest++);
- ((char *)src)++;
+ src++;
count--;
}
while (count > 3) {
bytecopy:
while (count--) {
writeb(*(char *)src, dest++);
- ((char *)src)++;
+ src++;
}
}
/* Then check for misaligned start address */
if (src & 1) {
*(u8 *)dest = readb(src);
- ((u8 *)src)++;
- ((u8 *)dest)++;
+ src++;
+ dest++;
count--;
if (count < 2) goto bytecopy;
}
if (src & 2) {
*(u16 *)dest = __raw_readw(src);
- ((u16 *)src)++;
- ((u16 *)dest)++;
- count-=2;
+ src += 2;
+ dest += 2;
+ count -= 2;
}
while (count > 3) {
shortcopy:
while (count > 1) {
*(u16 *)dest = __raw_readw(src);
- ((u16 *)src)++;
- ((u16 *)dest)++;
- count-=2;
+ src += 2;
+ dest += 2;
+ count -= 2;
}
bytecopy:
while (count--) {
*(char *)dest = readb(src);
- ((char *)src)++;
- ((char *)dest)++;
+ src++;
+ dest++;
}
}
*/
void insb (unsigned long port, void *dst, unsigned long count)
{
- while (((unsigned long)dst) & 0x3) {
+ unsigned char *p;
+
+ p = (unsigned char *)dst;
+
+ while (((unsigned long)p) & 0x3) {
if (!count)
return;
count--;
- *(unsigned char *) dst = inb(port);
- ((unsigned char *) dst)++;
+ *p = inb(port);
+ p++;
}
while (count >= 4) {
w |= inb(port) << 16;
w |= inb(port) << 8;
w |= inb(port);
- *(unsigned int *) dst = w;
- ((unsigned int *) dst)++;
+ *(unsigned int *) p = w;
+ p += 4;
}
while (count) {
--count;
- *(unsigned char *) dst = inb(port);
- ((unsigned char *) dst)++;
+ *p = inb(port);
+ p++;
}
}
void insw (unsigned long port, void *dst, unsigned long count)
{
unsigned int l = 0, l2;
+ unsigned char *p;
+
+ p = (unsigned char *)dst;
if (!count)
return;
- switch (((unsigned long) dst) & 0x3)
+ switch (((unsigned long)p) & 0x3)
{
case 0x00: /* Buffer 32-bit aligned */
while (count>=2) {
count -= 2;
l = cpu_to_le16(inw(port)) << 16;
l |= cpu_to_le16(inw(port));
- *(unsigned int *) dst = l;
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = l;
+ p += 4;
}
if (count) {
- *(unsigned short *) dst = cpu_to_le16(inw(port));
+ *(unsigned short *)p = cpu_to_le16(inw(port));
}
break;
case 0x02: /* Buffer 16-bit aligned */
- *(unsigned short *) dst = cpu_to_le16(inw(port));
- ((unsigned short *) dst)++;
+ *(unsigned short *)p = cpu_to_le16(inw(port));
+ p += 2;
count--;
while (count>=2) {
count -= 2;
l = cpu_to_le16(inw(port)) << 16;
l |= cpu_to_le16(inw(port));
- *(unsigned int *) dst = l;
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = l;
+ p += 4;
}
if (count) {
- *(unsigned short *) dst = cpu_to_le16(inw(port));
+ *(unsigned short *)p = cpu_to_le16(inw(port));
}
break;
--count;
l = cpu_to_le16(inw(port));
- *(unsigned char *) dst = l >> 8;
- ((unsigned char *) dst)++;
+ *p = l >> 8;
+ p++;
while (count--)
{
l2 = cpu_to_le16(inw(port));
- *(unsigned short *) dst = (l & 0xff) << 8 | (l2 >> 8);
- ((unsigned short *) dst)++;
+ *(unsigned short *)p = (l & 0xff) << 8 | (l2 >> 8);
+ p += 2;
l = l2;
}
- *(unsigned char *) dst = l & 0xff;
+ *p = l & 0xff;
break;
}
}
void insl (unsigned long port, void *dst, unsigned long count)
{
unsigned int l = 0, l2;
+ unsigned char *p;
+
+ p = (unsigned char *)dst;
if (!count)
return;
case 0x00: /* Buffer 32-bit aligned */
while (count--)
{
- *(unsigned int *) dst = cpu_to_le32(inl(port));
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = cpu_to_le32(inl(port));
+ p += 4;
}
break;
--count;
l = cpu_to_le32(inl(port));
- *(unsigned short *) dst = l >> 16;
- ((unsigned short *) dst)++;
+ *(unsigned short *)p = l >> 16;
+ p += 2;
while (count--)
{
l2 = cpu_to_le32(inl(port));
- *(unsigned int *) dst = (l & 0xffff) << 16 | (l2 >> 16);
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = (l & 0xffff) << 16 | (l2 >> 16);
+ p += 4;
l = l2;
}
- *(unsigned short *) dst = l & 0xffff;
+ *(unsigned short *)p = l & 0xffff;
break;
case 0x01: /* Buffer 8-bit aligned */
--count;
l = cpu_to_le32(inl(port));
- *(unsigned char *) dst = l >> 24;
- ((unsigned char *) dst)++;
- *(unsigned short *) dst = (l >> 8) & 0xffff;
- ((unsigned short *) dst)++;
+ *(unsigned char *)p = l >> 24;
+ p++;
+ *(unsigned short *)p = (l >> 8) & 0xffff;
+ p += 2;
while (count--)
{
l2 = cpu_to_le32(inl(port));
- *(unsigned int *) dst = (l & 0xff) << 24 | (l2 >> 8);
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = (l & 0xff) << 24 | (l2 >> 8);
+ p += 4;
l = l2;
}
- *(unsigned char *) dst = l & 0xff;
+ *p = l & 0xff;
break;
case 0x03: /* Buffer 8-bit aligned */
--count;
l = cpu_to_le32(inl(port));
- *(unsigned char *) dst = l >> 24;
- ((unsigned char *) dst)++;
+ *p = l >> 24;
+ p++;
while (count--)
{
l2 = cpu_to_le32(inl(port));
- *(unsigned int *) dst = (l & 0xffffff) << 8 | l2 >> 24;
- ((unsigned int *) dst)++;
+ *(unsigned int *)p = (l & 0xffffff) << 8 | l2 >> 24;
+ p += 4;
l = l2;
}
- *(unsigned short *) dst = (l >> 8) & 0xffff;
- ((unsigned short *) dst)++;
- *(unsigned char *) dst = l & 0xff;
+ *(unsigned short *)p = (l >> 8) & 0xffff;
+ p += 2;
+ *p = l & 0xff;
break;
}
}
*/
void outsb(unsigned long port, const void * src, unsigned long count)
{
+ const unsigned char *p;
+
+ p = (const unsigned char *)src;
while (count) {
count--;
- outb(*(char *)src, port);
- ((char *) src)++;
+ outb(*p, port);
+ p++;
}
}
void outsw (unsigned long port, const void *src, unsigned long count)
{
unsigned int l = 0, l2;
+ const unsigned char *p;
+
+ p = (const unsigned char *)src;
if (!count)
return;
- switch (((unsigned long) src) & 0x3)
+ switch (((unsigned long)p) & 0x3)
{
case 0x00: /* Buffer 32-bit aligned */
while (count>=2) {
count -= 2;
- l = *(unsigned int *) src;
- ((unsigned int *) src)++;
+ l = *(unsigned int *)p;
+ p += 4;
outw(le16_to_cpu(l >> 16), port);
outw(le16_to_cpu(l & 0xffff), port);
}
if (count) {
- outw(le16_to_cpu(*(unsigned short*)src), port);
+ outw(le16_to_cpu(*(unsigned short*)p), port);
}
break;
case 0x02: /* Buffer 16-bit aligned */
- outw(le16_to_cpu(*(unsigned short*)src), port);
- ((unsigned short *) src)++;
+ outw(le16_to_cpu(*(unsigned short*)p), port);
+ p += 2;
count--;
while (count>=2) {
count -= 2;
- l = *(unsigned int *) src;
- ((unsigned int *) src)++;
+ l = *(unsigned int *)p;
+ p += 4;
outw(le16_to_cpu(l >> 16), port);
outw(le16_to_cpu(l & 0xffff), port);
}
if (count) {
- outw(le16_to_cpu(*(unsigned short*)src), port);
+ outw(le16_to_cpu(*(unsigned short *)p), port);
}
break;
/* I don't bother with 32bit transfers
* in this case, 16bit will have to do -- DE */
- l = *(unsigned char *) src << 8;
- ((unsigned char *) src)++;
+ l = *p << 8;
+ p++;
count--;
while (count)
{
count--;
- l2 = *(unsigned short *) src;
- ((unsigned short *) src)++;
+ l2 = *(unsigned short *)p;
+ p += 2;
outw(le16_to_cpu(l | l2 >> 8), port);
l = l2 << 8;
}
- l2 = *(unsigned char *) src;
+ l2 = *(unsigned char *)p;
outw (le16_to_cpu(l | l2>>8), port);
break;
void outsl (unsigned long port, const void *src, unsigned long count)
{
unsigned int l = 0, l2;
+ const unsigned char *p;
+
+ p = (const unsigned char *)src;
if (!count)
return;
- switch (((unsigned long) src) & 0x3)
+ switch (((unsigned long)p) & 0x3)
{
case 0x00: /* Buffer 32-bit aligned */
while (count--)
{
- outl(le32_to_cpu(*(unsigned int *) src), port);
- ((unsigned int *) src)++;
+ outl(le32_to_cpu(*(unsigned int *)p), port);
+ p += 4;
}
break;
case 0x02: /* Buffer 16-bit aligned */
--count;
- l = *(unsigned short *) src;
- ((unsigned short *) src)++;
+ l = *(unsigned short *)p;
+ p += 2;
while (count--)
{
- l2 = *(unsigned int *) src;
- ((unsigned int *) src)++;
+ l2 = *(unsigned int *)p;
+ p += 4;
outl (le32_to_cpu(l << 16 | l2 >> 16), port);
l = l2;
}
- l2 = *(unsigned short *) src;
+ l2 = *(unsigned short *)p;
outl (le32_to_cpu(l << 16 | l2), port);
break;
case 0x01: /* Buffer 8-bit aligned */
--count;
-
- l = *(unsigned char *) src << 24;
- ((unsigned char *) src)++;
- l |= *(unsigned short *) src << 8;
- ((unsigned short *) src)++;
+
+ l = *p << 24;
+ p++;
+ l |= *(unsigned short *)p << 8;
+ p += 2;
+
while (count--)
{
- l2 = *(unsigned int *) src;
- ((unsigned int *) src)++;
+ l2 = *(unsigned int *)p;
+ p += 4;
outl (le32_to_cpu(l | l2 >> 24), port);
l = l2 << 8;
}
- l2 = *(unsigned char *) src;
- outl (le32_to_cpu(l | l2), port);
+ l2 = *p;
+ outl (le32_to_cpu(l | l2), port);
break;
case 0x03: /* Buffer 8-bit aligned */
--count;
- l = *(unsigned char *) src << 24;
- ((unsigned char *) src)++;
+ l = *p << 24;
+ p++;
+
while (count--)
{
- l2 = *(unsigned int *) src;
- ((unsigned int *) src)++;
+ l2 = *(unsigned int *)p;
+ p += 4;
outl (le32_to_cpu(l | l2 >> 8), port);
l = l2 << 24;
}
- l2 = *(unsigned short *) src << 16;
- ((unsigned short *) src)++;
- l2 |= *(unsigned char *) src;
+ l2 = *(unsigned short *)p << 16;
+ p += 2;
+ l2 |= *p;
outl (le32_to_cpu(l | l2), port);
break;
}
* Copyright 1999 SuSE GmbH
* changed by Philipp Rumpf
* Copyright 1999 Philipp Rumpf (prumpf@tux.org)
+ * Copyright 2004 Randolph Chung (tausq@debian.org)
*
*/
#include <asm/pgalloc.h>
#include <asm/tlb.h>
#include <asm/pdc_chassis.h>
+#include <asm/mmzone.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
extern char __init_begin, __init_end;
#ifdef CONFIG_DISCONTIGMEM
-struct node_map_data node_data[MAX_PHYSMEM_RANGES];
-bootmem_data_t bmem_data[MAX_PHYSMEM_RANGES];
-unsigned char *chunkmap;
-unsigned int maxchunkmap;
+struct node_map_data node_data[MAX_NUMNODES];
+bootmem_data_t bmem_data[MAX_NUMNODES];
+unsigned char pfnnid_map[PFNNID_MAP_MAX];
#endif
static struct resource data_resource = {
disable_sr_hashing(); /* Turn off space register hashing */
-#ifdef CONFIG_DISCONTIGMEM
- /*
- * The below is still true as of 2.4.2. If this is ever fixed,
- * we can remove this warning!
- */
-
- printk(KERN_WARNING "\n\n");
- printk(KERN_WARNING "CONFIG_DISCONTIGMEM is enabled, which is probably a mistake. This\n");
- printk(KERN_WARNING "option can lead to heavy swapping, even when there are gigabytes\n");
- printk(KERN_WARNING "of free memory.\n\n");
-#endif
-
-#ifdef __LP64__
-
-#ifndef CONFIG_DISCONTIGMEM
/*
* Sort the ranges. Since the number of ranges is typically
* small, and performance is not an issue here, just do
}
}
+#ifndef CONFIG_DISCONTIGMEM
/*
* Throw out ranges that are too far apart (controlled by
- * MAX_GAP). If CONFIG_DISCONTIGMEM wasn't implemented so
- * poorly, we would recommend enabling that option, but,
- * until it is fixed, this is the best way to go.
+ * MAX_GAP).
*/
for (i = 1; i < npmem_ranges; i++) {
(pmem_ranges[i-1].start_pfn +
pmem_ranges[i-1].pages) > MAX_GAP) {
npmem_ranges = i;
+ printk("Large gap in memory detected (%ld pages). "
+ "Consider turning on CONFIG_DISCONTIGMEM\n",
+ pmem_ranges[i].start_pfn -
+ (pmem_ranges[i-1].start_pfn +
+ pmem_ranges[i-1].pages));
break;
}
}
}
}
-#endif /* __LP64__ */
-
sysram_resource_count = npmem_ranges;
for (i = 0; i < sysram_resource_count; i++) {
struct resource *res = &sysram_resources[i];
mem_limit_func(); /* check for "mem=" argument */
mem_max = 0;
+ num_physpages = 0;
for (i = 0; i < npmem_ranges; i++) {
unsigned long rsize;
npmem_ranges = i + 1;
mem_max = mem_limit;
}
+ num_physpages += pmem_ranges[i].pages;
break;
}
+ num_physpages += pmem_ranges[i].pages;
mem_max += rsize;
}
printk(KERN_INFO "Total Memory: %ld Mb\n",mem_max >> 20);
#ifndef CONFIG_DISCONTIGMEM
-
/* Merge the ranges, keeping track of the holes */
{
bootmap_start_pfn = PAGE_ALIGN(__pa((unsigned long) &_end)) >> PAGE_SHIFT;
#ifdef CONFIG_DISCONTIGMEM
+ for (i = 0; i < MAX_PHYSMEM_RANGES; i++) {
+ memset(NODE_DATA(i), 0, sizeof(pg_data_t));
+ NODE_DATA(i)->bdata = &bmem_data[i];
+ }
+ memset(pfnnid_map, 0xff, sizeof(pfnnid_map));
+
+ numnodes = npmem_ranges;
+
for (i = 0; i < npmem_ranges; i++)
- node_data[i].pg_data.bdata = &bmem_data[i];
+ node_set_online(i);
#endif
+
/*
* Initialize and free the full range of memory in each range.
* Note that the only writing these routines do are to the bootmap,
void __init mem_init(void)
{
- int i;
-
high_memory = __va((max_pfn << PAGE_SHIFT));
- max_mapnr = (virt_to_page(high_memory - 1) - mem_map) + 1;
- num_physpages = 0;
- mem_map = zone_table[0]->zone_mem_map;
- for (i = 0; i < npmem_ranges; i++)
- num_physpages += free_all_bootmem_node(NODE_DATA(i));
- totalram_pages = num_physpages;
+#ifndef CONFIG_DISCONTIGMEM
+ max_mapnr = page_to_pfn(virt_to_page(high_memory - 1)) + 1;
+ mem_map = zone_table[ZONE_DMA]->zone_mem_map;
+ totalram_pages += free_all_bootmem();
+#else
+ {
+ int i;
+
+ for (i = 0; i < npmem_ranges; i++)
+ totalram_pages += free_all_bootmem_node(NODE_DATA(i));
+ }
+#endif
printk(KERN_INFO "Memory: %luk available\n", num_physpages << (PAGE_SHIFT-10));
show_free_areas();
printk(KERN_INFO "Free swap: %6ldkB\n",
nr_swap_pages<<(PAGE_SHIFT-10));
+#ifndef CONFIG_DISCONTIGMEM
i = max_mapnr;
while (i-- > 0) {
total++;
reserved++;
else if (PageSwapCache(mem_map+i))
cached++;
- else if (!atomic_read(&mem_map[i].count))
+ else if (!page_count(&mem_map[i]))
free++;
else
- shared += atomic_read(&mem_map[i].count) - 1;
+ shared += page_count(&mem_map[i]) - 1;
+ }
+#else
+ for (i = 0; i < npmem_ranges; i++) {
+ int j;
+
+ for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
+ struct page *p;
+
+ p = node_mem_map(i) + j - node_start_pfn(i);
+
+ total++;
+ if (PageReserved(p))
+ reserved++;
+ else if (PageSwapCache(p))
+ cached++;
+ else if (!page_count(p))
+ free++;
+ else
+ shared += page_count(p) - 1;
+ }
}
+#endif
printk(KERN_INFO "%d pages of RAM\n", total);
printk(KERN_INFO "%d reserved pages\n", reserved);
printk(KERN_INFO "%d pages shared\n", shared);
printk(KERN_INFO "%d pages swap cached\n", cached);
+
+
+#ifdef CONFIG_DISCONTIGMEM
+ {
+ struct zonelist *zl;
+ int i, j, k;
+
+ for (i = 0; i < npmem_ranges; i++) {
+ for (j = 0; j < MAX_NR_ZONES; j++) {
+ zl = NODE_DATA(i)->node_zonelists + j;
+
+ printk("Zone list for zone %d on node %d: ", j, i);
+ for (k = 0; zl->zones[k] != NULL; k++)
+ printk("[%d/%s] ", zl->zones[k]->zone_pgdat->node_id, zl->zones[k]->name);
+ printk("\n");
+ }
+ }
+ }
+#endif
}
#if PTRS_PER_PMD == 1
pmd = (pmd_t *)__pa(pg_dir);
#else
- pmd = (pmd_t *) (PAGE_MASK & pgd_val(*pg_dir));
+ pmd = (pmd_t *)pgd_address(*pg_dir);
/*
* pmd is physical at this point
pmd = (pmd_t *) __pa(pmd);
}
- pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pmd;
+ pgd_populate(NULL, pg_dir, __va(pmd));
#endif
pg_dir++;
* pg_table is physical at this point
*/
- pg_table = (pte_t *) (PAGE_MASK & pmd_val(*pmd));
+ pg_table = (pte_t *)pmd_address(*pmd);
if (!pg_table) {
pg_table = (pte_t *)
alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE);
pg_table = (pte_t *) __pa(pg_table);
}
- pmd_val(*pmd) = _PAGE_TABLE |
- (unsigned long) pg_table;
+ pmd_populate_kernel(NULL, pmd, __va(pg_table));
/* now change pg_table to kernel virtual addresses */
for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) {
pte_t pte;
-#if !defined(CONFIG_STI_CONSOLE)
-#warning STI console should explicitly allocate executable pages but does not
/*
* Map the fault vector writable so we can
* write the HPMC checksum.
&& address != gw_addr)
pte = __mk_pte(address, PAGE_KERNEL_RO);
else
-#endif
pte = __mk_pte(address, pgprot);
if (address >= end_paddr)
flush_tlb_all_local();
for (i = 0; i < npmem_ranges; i++) {
- unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0, };
+ unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
+ /* We have an IOMMU, so all memory can go into a single
+ ZONE_DMA zone. */
zones_size[ZONE_DMA] = pmem_ranges[i].pages;
+
free_area_init_node(i,NODE_DATA(i),NULL,zones_size,
- (pmem_ranges[i].start_pfn << PAGE_SHIFT),0);
- }
+ pmem_ranges[i].start_pfn, 0);
#ifdef CONFIG_DISCONTIGMEM
- /*
- * Initialize support for virt_to_page() macro.
- *
- * Note that MAX_ADDRESS is the largest virtual address that
- * we can map. However, since we map all physical memory into
- * the kernel address space, it also has an effect on the maximum
- * physical address we can map (MAX_ADDRESS - PAGE_OFFSET).
- */
-
- maxchunkmap = MAX_ADDRESS >> CHUNKSHIFT;
- chunkmap = (unsigned char *)alloc_bootmem(maxchunkmap);
-
- for (i = 0; i < maxchunkmap; i++)
- chunkmap[i] = BADCHUNK;
-
- for (i = 0; i < npmem_ranges; i++) {
-
- ADJ_NODE_MEM_MAP(i) = NODE_MEM_MAP(i) - pmem_ranges[i].start_pfn;
{
- unsigned long chunk_paddr;
- unsigned long end_paddr;
- int chunknum;
-
- chunk_paddr = (pmem_ranges[i].start_pfn << PAGE_SHIFT);
- end_paddr = chunk_paddr + (pmem_ranges[i].pages << PAGE_SHIFT);
- chunk_paddr &= CHUNKMASK;
-
- chunknum = (int)CHUNKNUM(chunk_paddr);
- while (chunk_paddr < end_paddr) {
- if (chunknum >= maxchunkmap)
- goto badchunkmap1;
- if (chunkmap[chunknum] != BADCHUNK)
- goto badchunkmap2;
- chunkmap[chunknum] = (unsigned char)i;
- chunk_paddr += CHUNKSZ;
- chunknum++;
- }
+ int j;
+ for (j = (node_start_pfn(i) >> PFNNID_SHIFT);
+ j <= (node_end_pfn(i) >> PFNNID_SHIFT);
+ j++) {
+ pfnnid_map[j] = i;
+ }
}
- }
-
- return;
-
-badchunkmap1:
- panic("paging_init: Physical address exceeds maximum address space!\n");
-badchunkmap2:
- panic("paging_init: Collision in chunk map array. CHUNKSZ needs to be smaller\n");
#endif
+ }
}
#ifdef CONFIG_PA20
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
#
# General setup
#
# Generic Driver Options
#
+CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=m
# CONFIG_DEBUG_DRIVER is not set
CONFIG_NET_DIVERT=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=m
CONFIG_EFS_FS=m
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_CRAMFS=m
CONFIG_VXFS_FS=m
CONFIG_HPFS_FS=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
/* Patch copy/page operations to cheetah optimized versions. */
call cheetah_patch_copyops
nop
- call cheetah_patch_pgcopyops
- nop
call cheetah_patch_cachetlbops
nop
.globl rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme, rtrap_xcall
rtrap_irq:
rtrap_clr_l6: clr %l6
-rtrap: ldub [%g6 + TI_CPU], %l0
+rtrap:
+ ldub [%g6 + TI_CPU], %l0
sethi %hi(irq_stat), %l2 ! &softirq_active
or %l2, %lo(irq_stat), %l2 ! &softirq_active
irqsz_patchme: sllx %l0, 0, %l0
#include <asm/uaccess.h>
#include <asm/timer.h>
#include <asm/starfire.h>
+#include <asm/tlb.h>
extern int linux_num_cpus;
extern void calibrate_delay(void);
}
}
-extern unsigned long xcall_flush_tlb_page;
extern unsigned long xcall_flush_tlb_mm;
-extern unsigned long xcall_flush_tlb_range;
+extern unsigned long xcall_flush_tlb_pending;
extern unsigned long xcall_flush_tlb_kernel_range;
extern unsigned long xcall_flush_tlb_all_spitfire;
extern unsigned long xcall_flush_tlb_all_cheetah;
int cpu = get_cpu();
if (atomic_read(&mm->mm_users) == 1) {
- /* See smp_flush_tlb_page for info about this. */
mm->cpu_vm_mask = cpumask_of_cpu(cpu);
goto local_flush_and_out;
}
}
}
-void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
- unsigned long end)
+void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs)
{
u32 ctx = CTX_HWBITS(mm->context);
int cpu = get_cpu();
- start &= PAGE_MASK;
- end = PAGE_ALIGN(end);
-
if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) {
mm->cpu_vm_mask = cpumask_of_cpu(cpu);
goto local_flush_and_out;
+ } else {
+ /* This optimization is not valid. Normally
+ * we will be holding the page_table_lock, but
+ * there is an exception which is copy_page_range()
+ * when forking. The lock is held during the individual
+ * page table updates in the parent, but not at the
+ * top level, which is where we are invoked.
+ */
+ if (0) {
+ cpumask_t this_cpu_mask = cpumask_of_cpu(cpu);
+
+ /* By virtue of running under the mm->page_table_lock,
+ * and mmu_context.h:switch_mm doing the same, the
+ * following operation is safe.
+ */
+ if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask))
+ goto local_flush_and_out;
+ }
}
- smp_cross_call_masked(&xcall_flush_tlb_range,
- ctx, start, end,
+ smp_cross_call_masked(&xcall_flush_tlb_pending,
+ ctx, nr, (unsigned long) vaddrs,
mm->cpu_vm_mask);
- local_flush_and_out:
- __flush_tlb_range(ctx, start, SECONDARY_CONTEXT,
- end, PAGE_SIZE, (end-start));
+local_flush_and_out:
+ __flush_tlb_pending(ctx, nr, vaddrs);
put_cpu();
}
}
}
-void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page)
-{
- {
- u32 ctx = CTX_HWBITS(mm->context);
- int cpu = get_cpu();
-
- page &= PAGE_MASK;
- if (mm == current->active_mm &&
- atomic_read(&mm->mm_users) == 1) {
- /* By virtue of being the current address space, and
- * having the only reference to it, the following
- * operation is safe.
- *
- * It would not be a win to perform the xcall tlb
- * flush in this case, because even if we switch back
- * to one of the other processors in cpu_vm_mask it
- * is almost certain that all TLB entries for this
- * context will be replaced by the time that happens.
- */
- mm->cpu_vm_mask = cpumask_of_cpu(cpu);
- goto local_flush_and_out;
- } else {
- cpumask_t this_cpu_mask = cpumask_of_cpu(cpu);
-
- /* By virtue of running under the mm->page_table_lock,
- * and mmu_context.h:switch_mm doing the same, the
- * following operation is safe.
- */
- if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask))
- goto local_flush_and_out;
- }
-
- /* OK, we have to actually perform the cross call. Most
- * likely this is a cloned mm or kswapd is kicking out pages
- * for a task which has run recently on another cpu.
- */
- smp_cross_call_masked(&xcall_flush_tlb_page,
- ctx, page, 0,
- mm->cpu_vm_mask);
- if (!cpu_isset(cpu, mm->cpu_vm_mask))
- return;
-
- local_flush_and_out:
- __flush_tlb_page(ctx, page, SECONDARY_CONTEXT);
-
- put_cpu();
- }
-}
-
/* CPU capture. */
/* #define CAPTURE_DEBUG */
extern unsigned long xcall_capture;
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(pte_alloc_one_kernel);
+EXPORT_SYMBOL(__pte_alloc_one_kernel);
#ifndef CONFIG_SMP
EXPORT_SYMBOL(pgt_quicklists);
#endif
#define TICK_SIZE (tick_nsec / 1000)
-static __inline__ void timer_check_rtc(void)
+static inline void timer_check_rtc(void)
{
/* last time the cmos clock got updated */
static long last_rtc_update;
void sparc64_do_profile(struct pt_regs *regs)
{
- unsigned long pc = regs->tpc;
- unsigned long o7 = regs->u_regs[UREG_RETPC];
+ unsigned long pc;
profile_hook(regs);
if (!prof_buffer)
return;
- {
- extern int rwlock_impl_begin, rwlock_impl_end;
- extern int atomic_impl_begin, atomic_impl_end;
- extern int __memcpy_begin, __memcpy_end;
- extern int __bzero_begin, __bzero_end;
- extern int __bitops_begin, __bitops_end;
-
- if ((pc >= (unsigned long) &atomic_impl_begin &&
- pc < (unsigned long) &atomic_impl_end) ||
- (pc >= (unsigned long) &rwlock_impl_begin &&
- pc < (unsigned long) &rwlock_impl_end) ||
- (pc >= (unsigned long) &__memcpy_begin &&
- pc < (unsigned long) &__memcpy_end) ||
- (pc >= (unsigned long) &__bzero_begin &&
- pc < (unsigned long) &__bzero_end) ||
- (pc >= (unsigned long) &__bitops_begin &&
- pc < (unsigned long) &__bitops_end))
- pc = o7;
-
- pc -= (unsigned long) _stext;
- pc >>= prof_shift;
-
- if(pc >= prof_len)
- pc = prof_len - 1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
- }
+ pc = regs->tpc;
+
+ pc -= (unsigned long) _stext;
+ pc >>= prof_shift;
+
+ if(pc >= prof_len)
+ pc = prof_len - 1;
+ atomic_inc((atomic_t *)&prof_buffer[pc]);
}
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
*/
void do_gettimeofday(struct timeval *tv)
{
- unsigned long flags;
unsigned long seq;
unsigned long usec, sec;
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
unsigned long lost;
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
+ seq = read_seqbegin(&xtime_lock);
usec = do_gettimeoffset();
lost = jiffies - wall_jiffies;
usec += lost * tick_usec;
sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
+ /* Believe it or not, this divide shows up on
+ * kernel profiles. The problem is that it is
+ * both 64-bit and signed. Happily, 32-bits
+ * of precision is all we really need and in
+ * doing so gcc ends up emitting a cheap multiply.
+ *
+ * XXX Why is tv_nsec 'long' and 'signed' in
+ * XXX the first place, can it even be negative?
+ */
+ usec += ((unsigned int) xtime.tv_nsec / 1000U);
+ } while (read_seqretry(&xtime_lock, seq));
while (usec >= 1000000) {
usec -= 1000000;
EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
-lib-y := PeeCeeI.o blockops.o strlen.o strncmp.o \
+lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \
memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \
VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \
VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \
.globl U3copy_from_user
U3copy_from_user: /* %o0=dst, %o1=src, %o2=len */
cmp %o2, 0
- be,pn %XCC, out
+ be,pn %XCC, 85f
or %o0, %o1, %o3
cmp %o2, 16
- bleu,a,pn %XCC, small_copy
+ bleu,a,pn %XCC, 80f
or %o3, %o2, %o3
cmp %o2, 256
- blu,pt %XCC, medium_copy
+ blu,pt %XCC, 70f
andcc %o3, 0x7, %g0
- ba,pt %xcc, enter
+ ba,pt %xcc, 1f
andcc %o0, 0x3f, %g2
/* Here len >= 256 and condition codes reflect execution
* of "andcc %o0, 0x7, %g2", done by caller.
*/
.align 64
-enter:
+1:
/* Is 'dst' already aligned on an 64-byte boundary? */
be,pt %XCC, 2f
2: VISEntryHalf
and %o1, 0x7, %g1
- ba,pt %xcc, begin
+ ba,pt %xcc, 1f
alignaddr %o1, %g0, %o1
.align 64
-begin:
-
- .globl U3copy_from_user_nop_1_6
-U3copy_from_user_nop_1_6:
- ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
- sethi %uhi(DCU_PE), %o3
- sllx %o3, 32, %o3
- or %g3, %o3, %o3
- stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
- membar #Sync
-
+1:
+ membar #StoreLoad | #StoreStore | #LoadStore
prefetcha [%o1 + 0x000] %asi, #one_read
prefetcha [%o1 + 0x040] %asi, #one_read
andn %o2, (0x40 - 1), %o4
sub %o4, 0x80, %o4
add %o1, 0x40, %o1
- ba,pt %xcc, loop
+ ba,pt %xcc, 1f
srl %o4, 6, %o3
.align 64
-loop:
+1:
EX3(ldda [%o1 + 0x008] %asi, %f2)
faligndata %f12, %f14, %f28
EX3(ldda [%o1 + 0x010] %asi, %f4)
faligndata %f10, %f12, %f26
subcc %o3, 0x01, %o3
add %o1, 0x40, %o1
- bg,pt %XCC, loop
+ bg,pt %XCC, 1b
add %o0, 0x40, %o0
/* Finally we copy the last full 64-byte block. */
-loopfini:
EX3(ldda [%o1 + 0x008] %asi, %f2)
faligndata %f12, %f14, %f28
EX3(ldda [%o1 + 0x010] %asi, %f4)
add %o0, 0x40, %o0
add %o1, 0x40, %o1
- .globl U3copy_from_user_nop_2_3
-U3copy_from_user_nop_2_3:
- mov PRIMARY_CONTEXT, %o3
- stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
- stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
-
membar #Sync
/* Now we copy the (len modulo 64) bytes at the end.
* Also notice how this code is careful not to perform a
* load past the end of the src buffer.
*/
-loopend:
and %o2, 0x3f, %o2
andcc %o2, 0x38, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 10f
subcc %g2, 0x8, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 10f
cmp %g1, 0
be,a,pt %XCC, 1f
subcc %g2, 0x8, %g2
faligndata %f0, %f2, %f8
std %f8, [%o0 + 0x00]
- be,pn %XCC, endcruft
+ be,pn %XCC, 10f
add %o0, 0x8, %o0
EX(ldda [%o1 + 0x08] %asi, %f0, add %o2, %g0)
add %o1, 0x8, %o1
* Note that %g1 is (src & 0x3) saved above before the
* alignaddr was performed.
*/
-endcruft:
+10:
cmp %o2, 0
add %o1, %g1, %o1
VISExitHalf
- be,pn %XCC, out
+ be,pn %XCC, 85f
sub %o0, %o1, %o3
andcc %g1, 0x7, %g0
- bne,pn %icc, small_copy_unaligned
+ bne,pn %icc, 90f
andcc %o2, 0x8, %g0
be,pt %icc, 1f
nop
add %o1, 0x2, %o1
1: andcc %o2, 0x1, %g0
- be,pt %icc, out
+ be,pt %icc, 85f
nop
EXNV(lduba [%o1] %asi, %o5, and %o2, 0x1)
- ba,pt %xcc, out
+ ba,pt %xcc, 85f
stb %o5, [%o1 + %o3]
-medium_copy: /* 16 < len <= 64 */
- bne,pn %XCC, small_copy_unaligned
+70: /* 16 < len <= 64 */
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-medium_copy_aligned:
andn %o2, 0x7, %o4
and %o2, 0x7, %o2
1: subcc %o4, 0x8, %o4
stw %o5, [%o1 + %o3]
add %o1, 0x4, %o1
1: cmp %o2, 0
- be,pt %XCC, out
+ be,pt %XCC, 85f
nop
- ba,pt %xcc, small_copy_unaligned
+ ba,pt %xcc, 90f
nop
-small_copy: /* 0 < len <= 16 */
+80: /* 0 < len <= 16 */
andcc %o3, 0x3, %g0
- bne,pn %XCC, small_copy_unaligned
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-small_copy_aligned:
+1:
subcc %o2, 4, %o2
EXNV(lduwa [%o1] %asi, %g1, add %o2, %g0)
stw %g1, [%o1 + %o3]
- bgu,pt %XCC, small_copy_aligned
+ bgu,pt %XCC, 1b
add %o1, 4, %o1
-out: retl
+85: retl
clr %o0
.align 32
-small_copy_unaligned:
+90:
subcc %o2, 1, %o2
EXNV(lduba [%o1] %asi, %g1, add %o2, %g0)
stb %g1, [%o1 + %o3]
- bgu,pt %XCC, small_copy_unaligned
+ bgu,pt %XCC, 90b
add %o1, 1, %o1
retl
clr %o0
nop
cmp %o2, 0
- be,pn %XCC, out
+ be,pn %XCC, 85f
or %o0, %o1, %o3
cmp %o2, 16
- bleu,a,pn %XCC, small_copy
+ bleu,a,pn %XCC, 80f
or %o3, %o2, %o3
cmp %o2, 256
- blu,pt %XCC, medium_copy
+ blu,pt %XCC, 70f
andcc %o3, 0x7, %g0
- ba,pt %xcc, enter
+ ba,pt %xcc, 1f
andcc %o0, 0x3f, %g2
/* Here len >= 256 and condition codes reflect execution
* of "andcc %o0, 0x7, %g2", done by caller.
*/
.align 64
-enter:
+1:
/* Is 'dst' already aligned on an 64-byte boundary? */
be,pt %XCC, 2f
2: VISEntryHalf
and %o1, 0x7, %g1
- ba,pt %xcc, begin
+ ba,pt %xcc, 1f
alignaddr %o1, %g0, %o1
.align 64
-begin:
-
- .globl U3copy_to_user_nop_1_6
-U3copy_to_user_nop_1_6:
- ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
- sethi %uhi(DCU_PE), %o3
- sllx %o3, 32, %o3
- or %g3, %o3, %o3
- stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
- membar #Sync
-
+1:
+ membar #StoreLoad | #StoreStore | #LoadStore
prefetch [%o1 + 0x000], #one_read
prefetch [%o1 + 0x040], #one_read
andn %o2, (0x40 - 1), %o4
sub %o4, 0x80, %o4
add %o1, 0x40, %o1
- ba,pt %xcc, loop
+ ba,pt %xcc, 1f
srl %o4, 6, %o3
.align 64
-loop:
+1:
ldd [%o1 + 0x008], %f2
faligndata %f12, %f14, %f28
ldd [%o1 + 0x010], %f4
faligndata %f10, %f12, %f26
subcc %o3, 0x01, %o3
add %o1, 0x40, %o1
- bg,pt %XCC, loop
+ bg,pt %XCC, 1b
add %o0, 0x40, %o0
/* Finally we copy the last full 64-byte block. */
-loopfini:
ldd [%o1 + 0x008], %f2
faligndata %f12, %f14, %f28
ldd [%o1 + 0x010], %f4
add %o0, 0x40, %o0
add %o1, 0x40, %o1
- .globl U3copy_to_user_nop_2_3
-U3copy_to_user_nop_2_3:
- mov PRIMARY_CONTEXT, %o3
- stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
- stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
-
membar #Sync
/* Now we copy the (len modulo 64) bytes at the end.
* Also notice how this code is careful not to perform a
* load past the end of the src buffer.
*/
-loopend:
and %o2, 0x3f, %o2
andcc %o2, 0x38, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
subcc %g2, 0x8, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
cmp %g1, 0
be,a,pt %XCC, 1f
subcc %g2, 0x8, %g2
faligndata %f0, %f2, %f8
EX(stda %f8, [%o0 + 0x00] %asi, add %o2, 0x8)
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
add %o0, 0x8, %o0
ldd [%o1 + 0x08], %f0
add %o1, 0x8, %o1
* Note that %g1 is (src & 0x3) saved above before the
* alignaddr was performed.
*/
-endcruft:
+2:
cmp %o2, 0
add %o1, %g1, %o1
VISExitHalf
- be,pn %XCC, out
+ be,pn %XCC, 85f
sub %o0, %o1, %o3
andcc %g1, 0x7, %g0
- bne,pn %icc, small_copy_unaligned
+ bne,pn %icc, 90f
andcc %o2, 0x8, %g0
be,pt %icc, 1f
nop
add %o1, 0x2, %o1
1: andcc %o2, 0x1, %g0
- be,pt %icc, out
+ be,pt %icc, 85f
nop
ldub [%o1], %o5
- ba,pt %xcc, out
+ ba,pt %xcc, 85f
EXNV(stba %o5, [%o1 + %o3] ASI_AIUS, and %o2, 0x1)
-medium_copy: /* 16 < len <= 64 */
- bne,pn %XCC, small_copy_unaligned
+70: /* 16 < len <= 64 */
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-medium_copy_aligned:
andn %o2, 0x7, %o4
and %o2, 0x7, %o2
1: subcc %o4, 0x8, %o4
EXNV3(stwa %o5, [%o1 + %o3] ASI_AIUS, add %o2, %g0)
add %o1, 0x4, %o1
1: cmp %o2, 0
- be,pt %XCC, out
+ be,pt %XCC, 85f
nop
- ba,pt %xcc, small_copy_unaligned
+ ba,pt %xcc, 90f
nop
-small_copy: /* 0 < len <= 16 */
+80: /* 0 < len <= 16 */
andcc %o3, 0x3, %g0
- bne,pn %XCC, small_copy_unaligned
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-small_copy_aligned:
+1:
subcc %o2, 4, %o2
lduw [%o1], %g1
EXNV3(stwa %g1, [%o1 + %o3] ASI_AIUS, add %o2, %g0)
- bgu,pt %XCC, small_copy_aligned
+ bgu,pt %XCC, 1b
add %o1, 4, %o1
-out: retl
+85: retl
clr %o0
.align 32
-small_copy_unaligned:
+90:
subcc %o2, 1, %o2
ldub [%o1], %g1
EXNV2(stba %g1, [%o1 + %o3] ASI_AIUS, add %o2, %g0)
- bgu,pt %XCC, small_copy_unaligned
+ bgu,pt %XCC, 90b
add %o1, 1, %o1
retl
clr %o0
U3memcpy: /* %o0=dst, %o1=src, %o2=len */
mov %o0, %g5
cmp %o2, 0
- be,pn %XCC, out
+ be,pn %XCC, 85f
or %o0, %o1, %o3
cmp %o2, 16
- bleu,a,pn %XCC, small_copy
+ bleu,a,pn %XCC, 70f
or %o3, %o2, %o3
cmp %o2, 256
- blu,pt %XCC, medium_copy
+ blu,pt %XCC, 80f
andcc %o3, 0x7, %g0
- ba,pt %xcc, enter
+ ba,pt %xcc, 1f
andcc %o0, 0x3f, %g2
/* Here len >= 256 and condition codes reflect execution
* of "andcc %o0, 0x7, %g2", done by caller.
*/
.align 64
-enter:
+1:
/* Is 'dst' already aligned on an 64-byte boundary? */
be,pt %XCC, 2f
2: VISEntryHalf
and %o1, 0x7, %g1
- ba,pt %xcc, begin
+ ba,pt %xcc, 1f
alignaddr %o1, %g0, %o1
.align 64
-begin:
-#ifdef __KERNEL__
- .globl U3memcpy_nop_1_6
-U3memcpy_nop_1_6:
- ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
- sethi %uhi(DCU_PE), %o3
- sllx %o3, 32, %o3
- or %g3, %o3, %o3
- stxa %o3, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
- membar #Sync
-#endif
+1:
+ membar #StoreLoad | #StoreStore | #LoadStore
prefetch [%o1 + 0x000], #one_read
prefetch [%o1 + 0x040], #one_read
andn %o2, (0x40 - 1), %o4
sub %o4, 0x80, %o4
add %o1, 0x40, %o1
- ba,pt %xcc, loop
+ ba,pt %xcc, 1f
srl %o4, 6, %o3
.align 64
-loop:
+1:
ldd [%o1 + 0x008], %f2
faligndata %f12, %f14, %f28
ldd [%o1 + 0x010], %f4
faligndata %f10, %f12, %f26
subcc %o3, 0x01, %o3
add %o1, 0x40, %o1
- bg,pt %XCC, loop
+ bg,pt %XCC, 1b
add %o0, 0x40, %o0
/* Finally we copy the last full 64-byte block. */
-loopfini:
ldd [%o1 + 0x008], %f2
faligndata %f12, %f14, %f28
ldd [%o1 + 0x010], %f4
stda %f16, [%o0] ASI_BLK_P
add %o0, 0x40, %o0
add %o1, 0x40, %o1
-#ifdef __KERNEL__
- .globl U3memcpy_nop_2_3
-U3memcpy_nop_2_3:
- mov PRIMARY_CONTEXT, %o3
- stxa %g0, [%o3] ASI_DMMU ! Flush P-cache
- stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
-#endif
membar #Sync
/* Now we copy the (len modulo 64) bytes at the end.
* Also notice how this code is careful not to perform a
* load past the end of the src buffer.
*/
-loopend:
and %o2, 0x3f, %o2
andcc %o2, 0x38, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
subcc %g2, 0x8, %g2
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
cmp %g1, 0
be,a,pt %XCC, 1f
subcc %g2, 0x8, %g2
faligndata %f0, %f2, %f8
std %f8, [%o0 + 0x00]
- be,pn %XCC, endcruft
+ be,pn %XCC, 2f
add %o0, 0x8, %o0
ldd [%o1 + 0x08], %f0
add %o1, 0x8, %o1
* Note that %g1 is (src & 0x3) saved above before the
* alignaddr was performed.
*/
-endcruft:
+2:
cmp %o2, 0
add %o1, %g1, %o1
VISExitHalf
- be,pn %XCC, out
+ be,pn %XCC, 85f
sub %o0, %o1, %o3
andcc %g1, 0x7, %g0
- bne,pn %icc, small_copy_unaligned
+ bne,pn %icc, 90f
andcc %o2, 0x8, %g0
be,pt %icc, 1f
nop
add %o1, 0x2, %o1
1: andcc %o2, 0x1, %g0
- be,pt %icc, out
+ be,pt %icc, 85f
nop
ldub [%o1], %o5
- ba,pt %xcc, out
+ ba,pt %xcc, 85f
stb %o5, [%o1 + %o3]
-medium_copy: /* 16 < len <= 64 */
- bne,pn %XCC, small_copy_unaligned
+70: /* 16 < len <= 64 */
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-medium_copy_aligned:
andn %o2, 0x7, %o4
and %o2, 0x7, %o2
1: subcc %o4, 0x8, %o4
stw %o5, [%o1 + %o3]
add %o1, 0x4, %o1
1: cmp %o2, 0
- be,pt %XCC, out
+ be,pt %XCC, 85f
nop
- ba,pt %xcc, small_copy_unaligned
+ ba,pt %xcc, 90f
nop
-small_copy: /* 0 < len <= 16 */
+80: /* 0 < len <= 16 */
andcc %o3, 0x3, %g0
- bne,pn %XCC, small_copy_unaligned
+ bne,pn %XCC, 90f
sub %o0, %o1, %o3
-small_copy_aligned:
+1:
subcc %o2, 4, %o2
lduw [%o1], %g1
stw %g1, [%o1 + %o3]
- bgu,pt %XCC, small_copy_aligned
+ bgu,pt %XCC, 1b
add %o1, 4, %o1
-out: retl
+85: retl
mov %g5, %o0
.align 32
-small_copy_unaligned:
+90:
subcc %o2, 1, %o2
ldub [%o1], %g1
stb %g1, [%o1 + %o3]
- bgu,pt %XCC, small_copy_unaligned
+ bgu,pt %XCC, 90b
add %o1, 1, %o1
retl
mov %g5, %o0
.text
.align 32
#ifdef __KERNEL__
- .globl __bzero_begin
-__bzero_begin:
.globl __bzero, __bzero_noasi
__bzero_noasi:
rd %asi, %g5
ba,pt %xcc, VISbzerofixup_ret0
sub %o1, %g2, %o0
#endif
- .globl __bzero_end
-__bzero_end:
.type bcopy,@function
#ifdef __KERNEL__
- .globl __memcpy_begin
-__memcpy_begin:
-
memcpy_private:
memcpy: mov ASI_P, asi_src ! IEU0 Group
brnz,pt %o2, __memcpy_entry ! CTI
or %g3, %lo(NOP), %g3; \
stw %g3, [%g2 + 0x4]; \
flush %g2;
-#define ULTRA3_PCACHE_DO_NOP(symbol) \
- sethi %hi(symbol##_nop_1_6), %g1; \
- or %g1, %lo(symbol##_nop_1_6), %g1; \
- sethi %hi(NOP), %g2; \
- stw %g2, [%g1 + 0x00]; \
- stw %g2, [%g1 + 0x04]; \
- flush %g1 + 0x00; \
- stw %g2, [%g1 + 0x08]; \
- stw %g2, [%g1 + 0x0c]; \
- flush %g1 + 0x08; \
- stw %g2, [%g1 + 0x10]; \
- stw %g2, [%g1 + 0x04]; \
- flush %g1 + 0x10; \
- sethi %hi(symbol##_nop_2_3), %g1; \
- or %g1, %lo(symbol##_nop_2_3), %g1; \
- stw %g2, [%g1 + 0x00]; \
- stw %g2, [%g1 + 0x04]; \
- flush %g1 + 0x00; \
- stw %g2, [%g1 + 0x08]; \
- flush %g1 + 0x08;
-
-#include <asm/dcu.h>
.globl cheetah_patch_copyops
cheetah_patch_copyops:
ULTRA3_DO_PATCH(__copy_from_user, U3copy_from_user)
ULTRA3_DO_PATCH(__copy_to_user, U3copy_to_user)
ULTRA3_DO_PATCH(__copy_in_user, U3copy_in_user)
-#if 0 /* Causes data corruption, nop out the optimization
- * for now -DaveM
- */
- ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
- sethi %uhi(DCU_PE), %o3
- sllx %o3, 32, %o3
- andcc %g3, %o3, %g0
- be,pn %xcc, pcache_disabled
- nop
-#endif
- ULTRA3_PCACHE_DO_NOP(U3memcpy)
- ULTRA3_PCACHE_DO_NOP(U3copy_from_user)
- ULTRA3_PCACHE_DO_NOP(U3copy_to_user)
- ULTRA3_PCACHE_DO_NOP(cheetah_copy_user_page)
-#if 0
-pcache_disabled:
-#endif
retl
nop
#undef BRANCH_ALWAYS
FPU_RETL
#ifdef __KERNEL__
- .globl __memcpy_end
-__memcpy_end:
-
.section .fixup
.align 4
VIScopyfixup_reto2:
.text
.align 64
- .globl atomic_impl_begin, atomic_impl_end
-
.globl __atomic_add
-atomic_impl_begin:
__atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
lduw [%o1], %g5
add %g5, %o0, %g7
retl
sub %g7, %o0, %o0
-atomic_impl_end:
.text
.align 64
- .globl __bitops_begin
-__bitops_begin:
-
.globl ___test_and_set_bit
___test_and_set_bit: /* %o0=nr, %o1=addr */
srlx %o0, 6, %g1
lduwa [%o1] ASI_PL, %g7
2: retl
membar #StoreLoad | #StoreStore
-
- .globl __bitops_end
-__bitops_end:
.text
.align 64
- .globl rwlock_impl_begin, rwlock_impl_end
-
/* The non-contention read lock usage is 2 cache lines. */
.globl __read_lock, __read_unlock
-rwlock_impl_begin:
__read_lock: /* %o0 = lock_ptr */
ldsw [%o0], %g5
brlz,pn %g5, __read_wait_for_writer
__write_trylock_fail:
retl
mov 0, %o0
-rwlock_impl_end:
EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
-obj-y := ultra.o fault.o init.o generic.o extable.o
+obj-y := ultra.o tlb.o fault.o init.o generic.o extable.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
if (tlb_type == spitfire &&
(vma->vm_flags & VM_EXEC) != 0 &&
vma->vm_file != NULL)
- set_thread_flag(TIF_BLKCOMMIT);
+ set_thread_fault_code(fault_code |
+ FAULT_CODE_BLKCOMMIT);
} else {
/* Allow reads even for write-only mappings */
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
fault_done:
/* These values are no longer needed, clear them. */
set_thread_fault_code(0);
- clear_thread_flag(TIF_BLKCOMMIT);
current_thread_info()->fault_address = 0;
}
#include <asm/spitfire.h>
#include <asm/sections.h>
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
extern void device_scan(void);
struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
put_cpu();
}
-/* When shared+writable mmaps of files go away, we lose all dirty
- * page state, so we have to deal with D-cache aliasing here.
- *
- * This code relies on the fact that flush_cache_range() is always
- * called for an area composed by a single VMA. It also assumes that
- * the MM's page_table_lock is held.
- */
-static inline void flush_cache_pte_range(struct mm_struct *mm, pmd_t *pmd, unsigned long address, unsigned long size)
-{
- unsigned long offset;
- pte_t *ptep;
-
- if (pmd_none(*pmd))
- return;
- ptep = pte_offset_map(pmd, address);
- offset = address & ~PMD_MASK;
- if (offset + size > PMD_SIZE)
- size = PMD_SIZE - offset;
- size &= PAGE_MASK;
- for (offset = 0; offset < size; ptep++, offset += PAGE_SIZE) {
- pte_t pte = *ptep;
-
- if (pte_none(pte))
- continue;
-
- if (pte_present(pte) && pte_dirty(pte)) {
- struct page *page;
- unsigned long pgaddr, uaddr;
- unsigned long pfn = pte_pfn(pte);
-
- if (!pfn_valid(pfn))
- continue;
- page = pfn_to_page(pfn);
- if (PageReserved(page) || !page_mapping(page))
- continue;
- pgaddr = (unsigned long) page_address(page);
- uaddr = address + offset;
- if ((pgaddr ^ uaddr) & (1 << 13))
- flush_dcache_page_all(mm, page);
- }
- }
- pte_unmap(ptep - 1);
-}
-
-static inline void flush_cache_pmd_range(struct mm_struct *mm, pgd_t *dir, unsigned long address, unsigned long size)
-{
- pmd_t *pmd;
- unsigned long end;
-
- if (pgd_none(*dir))
- return;
- pmd = pmd_offset(dir, address);
- end = address + size;
- if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
- end = ((address + PGDIR_SIZE) & PGDIR_MASK);
- do {
- flush_cache_pte_range(mm, pmd, address, end - address);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address < end);
-}
-
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- pgd_t *dir = pgd_offset(mm, start);
-
- if (mm == current->mm)
- flushw_user();
-
- if (vma->vm_file == NULL ||
- ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)))
- return;
-
- do {
- flush_cache_pmd_range(mm, dir, start, end - start);
- start = (start + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (start && (start < end));
-}
-
void flush_icache_range(unsigned long start, unsigned long end)
{
/* Cheetah has coherent I-cache. */
#else
#define DC_ALIAS_SHIFT 0
#endif
-pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
struct page *page;
unsigned long color;
*/
.text
.align 32
- .globl __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range
-__flush_tlb_page: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */
- ldxa [%o2] ASI_DMMU, %g2
- cmp %g2, %o0
- bne,pn %icc, __spitfire_flush_tlb_page_slow
- or %o1, 0x10, %g3
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- retl
- flush %g6
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
+ .globl __flush_tlb_mm
__flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
ldxa [%o1] ASI_DMMU, %g2
cmp %g2, %o0
nop
nop
-__flush_tlb_range: /* %o0=(ctx&TAG_CONTEXT_BITS), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
- * %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
- */
-#define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */
- cmp %o5, %o4
- bleu,pt %xcc, __flush_tlb_page
- srlx %o5, PAGE_SHIFT, %g5
- cmp %g5, TLB_MAGIC
- bgeu,pn %icc, __spitfire_flush_tlb_range_constant_time
- or %o1, 0x10, %g5
- ldxa [%o2] ASI_DMMU, %g2
- cmp %g2, %o0
-__spitfire_flush_tlb_range_page_by_page:
- bne,pn %icc, __spitfire_flush_tlb_range_pbp_slow
- sub %o5, %o4, %o5
-1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
- brnz,pt %o5, 1b
- sub %o5, %o4, %o5
- retl
- flush %g6
-__spitfire_flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g3
- mov ((SPITFIRE_HIGHEST_LOCKED_TLBENT-1) << 3), %g2
-
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
-
-1: ldxa [%g2] ASI_ITLB_TAG_READ, %o4
- and %o4, TAG_CONTEXT_BITS, %o5
- cmp %o5, %o0
- bne,pt %icc, 2f
- andn %o4, TAG_CONTEXT_BITS, %o4
- cmp %o4, %o1
- blu,pt %xcc, 2f
- cmp %o4, %o3
- blu,pn %xcc, 4f
-2: ldxa [%g2] ASI_DTLB_TAG_READ, %o4
- and %o4, TAG_CONTEXT_BITS, %o5
- cmp %o5, %o0
- andn %o4, TAG_CONTEXT_BITS, %o4
- bne,pt %icc, 3f
- cmp %o4, %o1
- blu,pt %xcc, 3f
- cmp %o4, %o3
- blu,pn %xcc, 5f
- nop
-3: brnz,pt %g2, 1b
- sub %g2, (1 << 3), %g2
- retl
- wrpr %g1, 0x0, %pstate
-4: stxa %g0, [%g3] ASI_IMMU
- stxa %g0, [%g2] ASI_ITLB_DATA_ACCESS
- flush %g6
-
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
-
- ba,pt %xcc, 2b
+ .align 32
+ .globl __flush_tlb_pending
+__flush_tlb_pending:
+ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
+ rdpr %pstate, %g5
+ sllx %o1, 3, %o1
+ andn %g5, PSTATE_IE, %g2
+ wrpr %g2, %pstate
+ mov SECONDARY_CONTEXT, %o4
+ ldxa [%o4] ASI_DMMU, %g2
+ stxa %o0, [%o4] ASI_DMMU
+1: sub %o1, (1 << 3), %o1
+ ldx [%o2 + %o1], %o3
+ andcc %o3, 1, %g0
+ andn %o3, 1, %o3
+ be,pn %icc, 2f
+ or %o3, 0x10, %o3
+ stxa %g0, [%o3] ASI_IMMU_DEMAP
+2: stxa %g0, [%o3] ASI_DMMU_DEMAP
+ membar #Sync
+ brnz,pt %o1, 1b
nop
-
-5: stxa %g0, [%g3] ASI_DMMU
- stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
+ stxa %g2, [%o4] ASI_DMMU
flush %g6
-
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
-
- ba,pt %xcc, 3b
- nop
+ retl
+ wrpr %g5, 0x0, %pstate
.align 32
.globl __flush_tlb_kernel_range
retl
wrpr %g1, 0, %pstate
-__spitfire_flush_tlb_page_slow:
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- stxa %o0, [%o2] ASI_DMMU
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- flush %g6
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- retl
- wrpr %g1, 0, %pstate
-
-__spitfire_flush_tlb_range_pbp_slow:
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- stxa %o0, [%o2] ASI_DMMU
-
-2: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
- brnz,pt %o5, 2b
- sub %o5, %o4, %o5
- flush %g6
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- retl
- wrpr %g1, 0x0, %pstate
-
/*
* The following code flushes one page_size worth.
*/
ba,a,pt %xcc, __prefill_itlb
/* Cheetah specific versions, patched at boot time. */
-__cheetah_flush_tlb_page: /* 14 insns */
- rdpr %pstate, %g5
- andn %g5, PSTATE_IE, %g2
- wrpr %g2, 0x0, %pstate
- wrpr %g0, 1, %tl
- mov PRIMARY_CONTEXT, %o2
- ldxa [%o2] ASI_DMMU, %g2
- stxa %o0, [%o2] ASI_DMMU
- stxa %g0, [%o1] ASI_DMMU_DEMAP
- stxa %g0, [%o1] ASI_IMMU_DEMAP
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- wrpr %g0, 0, %tl
- retl
- wrpr %g5, 0x0, %pstate
-
__cheetah_flush_tlb_mm: /* 15 insns */
rdpr %pstate, %g5
andn %g5, PSTATE_IE, %g2
retl
wrpr %g5, 0x0, %pstate
-__cheetah_flush_tlb_range: /* 20 insns */
- cmp %o5, %o4
- blu,pt %xcc, 9f
- rdpr %pstate, %g5
+__cheetah_flush_tlb_pending: /* 22 insns */
+ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
+ rdpr %pstate, %g5
+ sllx %o1, 3, %o1
andn %g5, PSTATE_IE, %g2
wrpr %g2, 0x0, %pstate
wrpr %g0, 1, %tl
- mov PRIMARY_CONTEXT, %o2
- sub %o5, %o4, %o5
- ldxa [%o2] ASI_DMMU, %g2
- stxa %o0, [%o2] ASI_DMMU
-1: stxa %g0, [%o1 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%o1 + %o5] ASI_IMMU_DEMAP
- membar #Sync
- brnz,pt %o5, 1b
- sub %o5, %o4, %o5
- stxa %g2, [%o2] ASI_DMMU
+ mov PRIMARY_CONTEXT, %o4
+ ldxa [%o4] ASI_DMMU, %g2
+ stxa %o0, [%o4] ASI_DMMU
+1: sub %o1, (1 << 3), %o1
+ ldx [%o2 + %o1], %o3
+ andcc %o3, 1, %g0
+ be,pn %icc, 2f
+ andn %o3, 1, %o3
+ stxa %g0, [%o3] ASI_IMMU_DEMAP
+2: stxa %g0, [%o3] ASI_DMMU_DEMAP
+ brnz,pt %o1, 1b
+ membar #Sync
+ stxa %g2, [%o4] ASI_DMMU
flush %g6
wrpr %g0, 0, %tl
-9: retl
+ retl
wrpr %g5, 0x0, %pstate
flush_dcpage_cheetah: /* 11 insns */
cheetah_patch_cachetlbops:
save %sp, -128, %sp
- sethi %hi(__flush_tlb_page), %o0
- or %o0, %lo(__flush_tlb_page), %o0
- sethi %hi(__cheetah_flush_tlb_page), %o1
- or %o1, %lo(__cheetah_flush_tlb_page), %o1
- call cheetah_patch_one
- mov 14, %o2
-
sethi %hi(__flush_tlb_mm), %o0
or %o0, %lo(__flush_tlb_mm), %o0
sethi %hi(__cheetah_flush_tlb_mm), %o1
call cheetah_patch_one
mov 15, %o2
- sethi %hi(__flush_tlb_range), %o0
- or %o0, %lo(__flush_tlb_range), %o0
- sethi %hi(__cheetah_flush_tlb_range), %o1
- or %o1, %lo(__cheetah_flush_tlb_range), %o1
+ sethi %hi(__flush_tlb_pending), %o0
+ or %o0, %lo(__flush_tlb_pending), %o0
+ sethi %hi(__cheetah_flush_tlb_pending), %o1
+ or %o1, %lo(__cheetah_flush_tlb_pending), %o1
call cheetah_patch_one
- mov 20, %o2
+ mov 22, %o2
sethi %hi(__flush_dcache_page), %o0
or %o0, %lo(__flush_dcache_page), %o0
* TODO: Make xcall TLB range flushes use the tricks above... -DaveM
*/
.align 32
- .globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
-xcall_flush_tlb_page:
- mov PRIMARY_CONTEXT, %g2
- ldxa [%g2] ASI_DMMU, %g3
- stxa %g5, [%g2] ASI_DMMU
- stxa %g0, [%g1] ASI_DMMU_DEMAP
- stxa %g0, [%g1] ASI_IMMU_DEMAP
- stxa %g3, [%g2] ASI_DMMU
- retry
- nop
-
+ .globl xcall_flush_tlb_mm
xcall_flush_tlb_mm:
mov PRIMARY_CONTEXT, %g2
mov 0x40, %g4
stxa %g3, [%g2] ASI_DMMU
retry
-xcall_flush_tlb_range:
- sethi %hi(PAGE_SIZE - 1), %g2
- or %g2, %lo(PAGE_SIZE - 1), %g2
- andn %g1, %g2, %g1
- andn %g7, %g2, %g7
- sub %g7, %g1, %g3
- add %g2, 1, %g2
- srlx %g3, PAGE_SHIFT, %g4
- cmp %g4, 96
-
- bgu,pn %icc, xcall_flush_tlb_mm
- mov PRIMARY_CONTEXT, %g4
- ldxa [%g4] ASI_DMMU, %g7
- sub %g3, %g2, %g3
+ .globl xcall_flush_tlb_pending
+xcall_flush_tlb_pending:
+ /* %g5=context, %g1=nr, %g7=vaddrs[] */
+ sllx %g1, 3, %g1
+ mov PRIMARY_CONTEXT, %g4
+ ldxa [%g4] ASI_DMMU, %g2
stxa %g5, [%g4] ASI_DMMU
- nop
- nop
- nop
-
-1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
- stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
+1: sub %g1, (1 << 3), %g1
+ ldx [%g7 + %g1], %g5
+ andcc %g5, 0x1, %g0
+ be,pn %icc, 2f
+
+ andn %g5, 0x1, %g5
+ stxa %g0, [%g5] ASI_IMMU_DEMAP
+2: stxa %g0, [%g5] ASI_DMMU_DEMAP
membar #Sync
- brnz,pt %g3, 1b
- sub %g3, %g2, %g3
- stxa %g7, [%g4] ASI_DMMU
+ brnz,pt %g1, 1b
+ nop
+ stxa %g2, [%g4] ASI_DMMU
retry
- nop
- nop
.globl xcall_flush_tlb_kernel_range
xcall_flush_tlb_kernel_range:
retry
nop
nop
- nop
/* This runs in a very controlled environment, so we do
* not need to worry about BH races etc.
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
WEP, but it should not be for other purposes because of the
weakness of the algorithm.
+config CRYPTO_KHAZAD
+ tristate "Khazad cipher algorithm"
+ depends on CRYPTO
+ help
+ Khazad cipher algorithm.
+
+ Khazad was a finalist in the initial NESSIE competition. It is
+ an algorithm optimized for 64-bit processors with good performance
+ on 32-bit processors. Khazad uses an 128 bit key size.
+
+ See also:
+ http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html
+
config CRYPTO_DEFLATE
tristate "Deflate compression algorithm"
depends on CRYPTO
obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
obj-$(CONFIG_CRYPTO_TEA) += tea.o
+obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
test_cipher ("xtea", MODE_ECB, ENCRYPT, xtea_enc_tv_template, XTEA_ENC_TEST_VECTORS);
test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
+ //KHAZAD
+ test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
+ test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
+
test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
test_deflate();
test_cipher ("xtea", MODE_ECB, DECRYPT, xtea_dec_tv_template, XTEA_DEC_TEST_VECTORS);
break;
+ case 21:
+ test_cipher ("khazad", MODE_ECB, ENCRYPT, khazad_enc_tv_template, KHAZAD_ENC_TEST_VECTORS);
+ test_cipher ("khazad", MODE_ECB, DECRYPT, khazad_dec_tv_template, KHAZAD_DEC_TEST_VECTORS);
+ break;
+
#ifdef CONFIG_CRYPTO_HMAC
case 100:
test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
}
};
+/*
+ * KHAZAD test vectors.
+ */
+#define KHAZAD_ENC_TEST_VECTORS 5
+#define KHAZAD_DEC_TEST_VECTORS 5
+struct cipher_testvec khazad_enc_tv_template[] = {
+ {
+ .key = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .klen = 16,
+ .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .ilen = 8,
+ .result = { 0x49, 0xa4, 0xce, 0x32, 0xac, 0x19, 0x0e, 0x3f },
+ .rlen = 8,
+ }, {
+ .key = { 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38 },
+ .klen = 16,
+ .input = { 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38 },
+ .ilen = 8,
+ .result = { 0x7e, 0x82, 0x12, 0xa1, 0Xd9, 0X5b, 0Xe4, 0Xf9 },
+ .rlen = 8,
+ }, {
+ .key = { 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2,
+ 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2 },
+ .klen = 16,
+ .input = { 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2 },
+ .ilen = 8,
+ .result = { 0Xaa, 0Xbe, 0Xc1, 0X95, 0Xc5, 0X94, 0X1a, 0X9c },
+ .rlen = 8,
+ }, {
+ .key = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .klen = 16,
+ .input = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .ilen = 8,
+ .result = { 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 },
+ .rlen = 8,
+ }, {
+ .key = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .klen = 16,
+ .input = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f ,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .ilen = 16,
+ .result = { 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 ,
+ 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 },
+ .rlen = 16,
+ },
+};
+
+struct cipher_testvec khazad_dec_tv_template[] = {
+ {
+ .key = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .klen = 16,
+ .input = { 0X49, 0Xa4, 0Xce, 0X32, 0Xac, 0X19, 0X0e, 0X3f },
+ .ilen = 8,
+ .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .rlen = 8,
+ }, {
+ .key = { 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
+ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38 },
+ .klen = 16,
+ .input = { 0X7e, 0X82, 0X12, 0Xa1, 0Xd9, 0X5b, 0Xe4, 0Xf9 },
+ .ilen = 8,
+ .result = { 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38 },
+ .rlen = 8,
+ }, {
+ .key = { 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2,
+ 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2 },
+ .klen = 16,
+ .input = { 0Xaa, 0Xbe, 0Xc1, 0X95, 0Xc5, 0X94, 0X1a, 0X9c },
+ .ilen = 8,
+ .result = { 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2, 0Xa2 },
+ .rlen = 8,
+ }, {
+ .key = { 0x2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .klen = 16,
+ .input = { 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 },
+ .ilen = 8,
+ .result = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .rlen = 8,
+ }, {
+ .key = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .klen = 16,
+ .input = { 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 ,
+ 0X04, 0X74, 0Xf5, 0X70, 0X50, 0X16, 0Xd3, 0Xb8 },
+ .ilen = 16,
+ .result = { 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f ,
+ 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f, 0X2f },
+ .rlen = 16,
+ },
+};
/*
* Compression stuff.
printk("Using %s io scheduler\n", chosen_elevator->elevator_name);
}
- if (elevator_init(q, chosen_elevator))
- goto out_elv;
-
q->request_fn = rfn;
q->back_merge_fn = ll_back_merge_fn;
q->front_merge_fn = ll_front_merge_fn;
blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
- return q;
-out_elv:
+ /*
+ * all done
+ */
+ if (!elevator_init(q, chosen_elevator))
+ return q;
+
blk_cleanup_queue(q);
out_init:
kmem_cache_free(requestq_cachep, q);
return queue_work(kblockd_workqueue, work);
}
+EXPORT_SYMBOL(kblockd_schedule_work);
+
void kblockd_flush(void)
{
flush_workqueue(kblockd_workqueue);
unsigned cmd, unsigned long arg)
{
struct pcd_unit *cd = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(&cd->info, inode, cmd, arg);
+ return cdrom_ioctl(file, &cd->info, inode, cmd, arg);
}
static int pcd_block_media_changed(struct gendisk *disk)
return put_user(1, p);
}
-static int sg_io(request_queue_t *q, struct gendisk *bd_disk,
- struct sg_io_hdr *hdr)
+#define CMD_READ_SAFE 0x01
+#define CMD_WRITE_SAFE 0x02
+#define safe_for_read(cmd) [cmd] = CMD_READ_SAFE
+#define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE
+
+static int verify_command(struct file *file, unsigned char *cmd)
+{
+ static const unsigned char cmd_type[256] = {
+
+ /* Basic read-only commands */
+ safe_for_read(TEST_UNIT_READY),
+ safe_for_read(REQUEST_SENSE),
+ safe_for_read(READ_6),
+ safe_for_read(READ_10),
+ safe_for_read(READ_12),
+ safe_for_read(READ_16),
+ safe_for_read(READ_BUFFER),
+ safe_for_read(READ_LONG),
+ safe_for_read(INQUIRY),
+ safe_for_read(MODE_SENSE),
+ safe_for_read(MODE_SENSE_10),
+ safe_for_read(START_STOP),
+
+ /* Audio CD commands */
+ safe_for_read(GPCMD_PLAY_CD),
+ safe_for_read(GPCMD_PLAY_AUDIO_10),
+ safe_for_read(GPCMD_PLAY_AUDIO_MSF),
+ safe_for_read(GPCMD_PLAY_AUDIO_TI),
+
+ /* CD/DVD data reading */
+ safe_for_read(GPCMD_READ_CD),
+ safe_for_read(GPCMD_READ_CD_MSF),
+ safe_for_read(GPCMD_READ_DISC_INFO),
+ safe_for_read(GPCMD_READ_CDVD_CAPACITY),
+ safe_for_read(GPCMD_READ_DVD_STRUCTURE),
+ safe_for_read(GPCMD_READ_HEADER),
+ safe_for_read(GPCMD_READ_TRACK_RZONE_INFO),
+ safe_for_read(GPCMD_READ_SUBCHANNEL),
+ safe_for_read(GPCMD_READ_TOC_PMA_ATIP),
+ safe_for_read(GPCMD_REPORT_KEY),
+ safe_for_read(GPCMD_SCAN),
+
+ /* Basic writing commands */
+ safe_for_write(WRITE_6),
+ safe_for_write(WRITE_10),
+ safe_for_write(WRITE_VERIFY),
+ safe_for_write(WRITE_12),
+ safe_for_write(WRITE_VERIFY_12),
+ safe_for_write(WRITE_16),
+ safe_for_write(WRITE_BUFFER),
+ safe_for_write(WRITE_LONG),
+ };
+ unsigned char type = cmd_type[cmd[0]];
+
+ /* Anybody who can open the device can do a read-safe command */
+ if (type & CMD_READ_SAFE)
+ return 0;
+
+ /* Write-safe commands just require a writable open.. */
+ if (type & CMD_WRITE_SAFE) {
+ if (file->f_mode & FMODE_WRITE)
+ return 0;
+ }
+
+ /* And root can do any command.. */
+ if (capable(CAP_SYS_RAWIO))
+ return 0;
+
+ /* Otherwise fail it with an "Operation not permitted" */
+ return -EPERM;
+}
+
+static int sg_io(struct file *file, request_queue_t *q,
+ struct gendisk *bd_disk, struct sg_io_hdr *hdr)
{
unsigned long start_time;
int reading, writing;
return -EINVAL;
if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len))
return -EFAULT;
+ if (verify_command(file, cmd))
+ return -EPERM;
/*
* we'll do that later
#define READ_DEFECT_DATA_TIMEOUT (60 * HZ )
#define OMAX_SB_LEN 16 /* For backward compatibility */
-static int sg_scsi_ioctl(request_queue_t *q, struct gendisk *bd_disk,
- Scsi_Ioctl_Command __user *sic)
+static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
+ struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
{
struct request *rq;
int err, in_len, out_len, bytes, opcode, cmdlen;
if (copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error;
+ err = verify_command(file, rq->cmd);
+ if (err)
+ goto error;
+
switch (opcode) {
case SEND_DIAGNOSTIC:
case FORMAT_UNIT:
return err;
}
-int scsi_cmd_ioctl(struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
+int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
{
request_queue_t *q;
struct request *rq;
err = -EFAULT;
if (copy_from_user(&hdr, arg, sizeof(hdr)))
break;
- err = sg_io(q, bd_disk, &hdr);
+ err = sg_io(file, q, bd_disk, &hdr);
if (err == -EFAULT)
break;
hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
hdr.cmd_len = sizeof(cgc.cmd);
- err = sg_io(q, bd_disk, &hdr);
+ err = sg_io(file, q, bd_disk, &hdr);
if (err == -EFAULT)
break;
if (!arg)
break;
- err = sg_scsi_ioctl(q, bd_disk, arg);
+ err = sg_scsi_ioctl(file, q, bd_disk, arg);
break;
case CDROMCLOSETRAY:
close = 1;
if (!cdrom_is_mrw(cdi, &mrw_write))
mrw = 1;
- (void) cdrom_is_random_writable(cdi, &ram_write);
-
+ if (CDROM_CAN(CDC_MO_DRIVE))
+ ram_write = 1;
+ else
+ (void) cdrom_is_random_writable(cdi, &ram_write);
+
if (mrw)
cdi->mask &= ~CDC_MRW;
else
else if (CDROM_CAN(CDC_DVD_RAM))
ret = cdrom_dvdram_open_write(cdi);
else if (CDROM_CAN(CDC_RAM) &&
- !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW))
+ !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW|CDC_MO_DRIVE))
ret = cdrom_ram_open_write(cdi);
else if (CDROM_CAN(CDC_MO_DRIVE))
ret = mo_open_write(cdi);
* these days. ATAPI / SCSI specific code now mainly resides in
* mmc_ioct().
*/
-int cdrom_ioctl(struct cdrom_device_info *cdi, struct inode *ip,
- unsigned int cmd, unsigned long arg)
+int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
+ struct inode *ip, unsigned int cmd, unsigned long arg)
{
struct cdrom_device_ops *cdo = cdi->ops;
int ret;
/* Try the generic SCSI command ioctl's first.. */
- ret = scsi_cmd_ioctl(ip->i_bdev->bd_disk, cmd, (void __user *)arg);
+ ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, (void __user *)arg);
if (ret != -ENOTTY)
return ret;
static int scd_block_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg)
{
- return cdrom_ioctl(&scd_info, inode, cmd, arg);
+ return cdrom_ioctl(file, &scd_info, inode, cmd, arg);
}
static int scd_block_media_changed(struct gendisk *disk)
static int cm206_block_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg)
{
- return cdrom_ioctl(&cm206_info, inode, cmd, arg);
+ return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
}
static int cm206_block_media_changed(struct gendisk *disk)
static int mcd_block_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg)
{
- return cdrom_ioctl(&mcd_info, inode, cmd, arg);
+ return cdrom_ioctl(file, &mcd_info, inode, cmd, arg);
}
static int mcd_block_media_changed(struct gendisk *disk)
unsigned cmd, unsigned long arg)
{
struct s_drive_stuff *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(&p->info, inode, cmd, arg);
+ return cdrom_ioctl(file, &p->info, inode, cmd, arg);
}
static int mcdx_block_media_changed(struct gendisk *disk)
unsigned cmd, unsigned long arg)
{
struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(p->sbpcd_infop, inode, cmd, arg);
+ return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
}
static int sbpcd_block_media_changed(struct gendisk *disk)
unsigned cmd, unsigned long arg)
{
struct disk_info *di = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(&di->viocd_info, inode, cmd, arg);
+ return cdrom_ioctl(file, &di->viocd_info, inode, cmd, arg);
}
static int viocd_blk_media_changed(struct gendisk *disk)
} else {
time = jiffies;
}
+#elif defined (__sparc_v9__)
+ unsigned long tick = tick_ops->get_tick();
+
+ time = (unsigned int) tick;
+ num ^= (tick >> 32UL);
#else
time = jiffies;
#endif
{
struct block_device *bdev = inode->i_bdev;
ide_drive_t *drive = bdev->bd_disk->private_data;
- int err = generic_ide_ioctl(bdev, cmd, arg);
+ int err = generic_ide_ioctl(file, bdev, cmd, arg);
if (err == -EINVAL) {
struct cdrom_info *info = drive->driver_data;
- err = cdrom_ioctl(&info->devinfo, inode, cmd, arg);
+ err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
}
return err;
}
unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = inode->i_bdev;
- return generic_ide_ioctl(bdev, cmd, arg);
+ return generic_ide_ioctl(file, bdev, cmd, arg);
}
static int idedisk_media_changed(struct gendisk *disk)
ide_drive_t *drive = bdev->bd_disk->private_data;
idefloppy_floppy_t *floppy = drive->driver_data;
void __user *argp = (void __user *)arg;
- int err = generic_ide_ioctl(bdev, cmd, arg);
+ int err = generic_ide_ioctl(file, bdev, cmd, arg);
int prevent = (arg) ? 1 : 0;
idefloppy_pc_t pc;
if (err != -EINVAL)
{
struct block_device *bdev = inode->i_bdev;
ide_drive_t *drive = bdev->bd_disk->private_data;
- int err = generic_ide_ioctl(bdev, cmd, arg);
+ int err = generic_ide_ioctl(file, bdev, cmd, arg);
if (err == -EINVAL)
err = idetape_blkdev_ioctl(drive, cmd, arg);
return err;
return ide_do_drive_cmd(drive, &rq, ide_head_wait);
}
-int generic_ide_ioctl(struct block_device *bdev, unsigned int cmd,
- unsigned long arg)
+int generic_ide_ioctl(struct file *file, struct block_device *bdev,
+ unsigned int cmd, unsigned long arg)
{
ide_drive_t *drive = bdev->bd_disk->private_data;
ide_settings_t *setting;
case CDROMEJECT:
case CDROMCLOSETRAY:
- return scsi_cmd_ioctl(bdev->bd_disk, cmd, p);
+ return scsi_cmd_ioctl(file, bdev->bd_disk, cmd, p);
case HDIO_GET_BUSSTATE:
if (!capable(CAP_SYS_ADMIN))
-# $Id: Kconfig,v 1.5 2004/06/04 15:59:32 gleixner Exp $
+# $Id: Kconfig,v 1.6 2004/08/09 13:19:42 dwmw2 Exp $
menu "Memory Technology Devices (MTD)"
Determines the verbosity level of the MTD debugging messages.
config MTD_PARTITIONS
- tristate "MTD partitioning support"
+ bool "MTD partitioning support"
depends on MTD
help
If you have a device which needs to divide its flash chip(s) up
#
# Makefile for the memory technology device drivers.
#
-# $Id: Makefile.common,v 1.3 2004/07/12 16:07:30 dwmw2 Exp $
+# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $
# Core functionality.
-obj-$(CONFIG_MTD) += mtdcore.o
+mtd-y := mtdcore.o
+mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
+obj-$(CONFIG_MTD) += $(mtd-y)
+
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
-obj-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
*
* Author: Jonas Holmberg <jonas.holmberg@axis.com>
*
- * $Id: amd_flash.c,v 1.24 2004/07/12 13:34:30 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.25 2004/08/09 13:19:43 dwmw2 Exp $
*
* Copyright (c) 2001 Axis Communications AB
*
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback) {
- instr->callback(instr);
- }
+ mtd_erase_callback(instr);
return 0;
}
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0001.c,v 1.153 2004/07/12 21:52:20 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.154 2004/08/09 13:19:43 dwmw2 Exp $
*
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
*
* This code is GPL
*
- * $Id: cfi_cmdset_0002.c,v 1.103 2004/07/14 16:24:03 dwmw2 Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.106 2004/08/09 14:02:32 dwmw2 Exp $
*
*/
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
return ret;
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
*
* (C) 2000 Red Hat. GPL'd
*
- * $Id: cfi_cmdset_0020.c,v 1.14 2004/07/20 02:44:25 dwmw2 Exp $
+ * $Id: cfi_cmdset_0020.c,v 1.15 2004/08/09 13:19:43 dwmw2 Exp $
*
* 10/10/2000 Nicolas Pitre <nico@cam.org>
* - completely revamped method functions so they are aware and
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
* not going to guess how to send commands to them, plus I expect they will
* all speak CFI..
*
- * $Id: jedec.c,v 1.20 2004/07/12 14:03:01 dwmw2 Exp $
+ * $Id: jedec.c,v 1.21 2004/08/09 13:19:43 dwmw2 Exp $
*/
#include <linux/init.h>
//printk("done\n");
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
#undef flread
/*
* Common code to handle map devices which are simple RAM
* (C) 2000 Red Hat. GPL'd.
- * $Id: map_ram.c,v 1.19 2004/07/12 21:58:44 dwmw2 Exp $
+ * $Id: map_ram.c,v 1.20 2004/08/09 13:19:43 dwmw2 Exp $
*/
#include <linux/module.h>
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
* Copyright 2000,2001 David A. Schleef <ds@schleef.org>
* 2000,2001 Lineo, Inc.
*
- * $Id: sharp.c,v 1.13 2004/07/12 14:06:34 dwmw2 Exp $
+ * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $
*
* Devices supported:
* LH28F016SCT Symmetrical block flash memory, 2Mx8
}
instr->state = MTD_ERASE_DONE;
- if(instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.10 2004/07/15 00:34:49 dwmw2 Exp $
+# $Id: Kconfig,v 1.12 2004/08/10 13:12:18 dwmw2 Exp $
menu "Self-contained MTD device drivers"
depends on MTD!=n
comment "Disk-On-Chip Device Drivers"
config MTD_DOC2000
- tristate "M-Systems Disk-On-Chip 2000 and Millennium"
+ tristate "M-Systems Disk-On-Chip 2000 and Millennium (DEPRECATED)"
depends on MTD
---help---
This provides an MTD device driver for the M-Systems DiskOnChip
emulate a block device by using a kind of file system on the flash
chips.
+ NOTE: This driver is deprecated and will probably be removed soon.
+ Please try the new DiskOnChip driver under "NAND Flash Device
+ Drivers".
+
config MTD_DOC2001
- tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (see help)"
+ tristate "M-Systems Disk-On-Chip Millennium-only alternative driver (DEPRECATED)"
depends on MTD
---help---
This provides an alternative MTD device driver for the M-Systems
emulate a block device by using a kind of file system on the flash
chips.
+ NOTE: This driver is deprecated and will probably be removed soon.
+ Please try the new DiskOnChip driver under "NAND Flash Device
+ Drivers".
+
config MTD_DOC2001PLUS
tristate "M-Systems Disk-On-Chip Millennium Plus"
depends on MTD
to emulate a block device by using a kind of file system on the
flash chips.
+ NOTE: This driver will soon be replaced by the new DiskOnChip driver
+ under "NAND Flash Device Drivers" (currently that driver does not
+ support all Millennium Plus devices).
+
config MTD_DOCPROBE
tristate
default m if MTD_DOC2001!=y && MTD_DOC2000!=y && MTD_DOC2001PLUS!=y && (MTD_DOC2001=m || MTD_DOC2000=m || MTD_DOC2001PLUS=m)
default y if MTD_DOC2001=y || MTD_DOC2000=y || MTD_DOC2001PLUS=y
help
- This isn't a real config option, it's derived.
+ This isn't a real config option; it's derived.
config MTD_DOCECC
tristate
default m if MTD_DOCPROBE!=y && MTD_NAND_DISKONCHIP!=y && (MTD_DOCPROBE=m || MTD_NAND_DISKONCHIP=m)
default y if MTD_DOCPROBE=y || MTD_NAND_DISKONCHIP=y
help
- This isn't a real config option, it's derived.
+ This isn't a real config option; it's derived.
config MTD_DOCPROBE_ADVANCED
bool "Advanced detection options for DiskOnChip"
/*
- * $Id: blkmtd-25.c,v 1.6 2004/07/15 15:09:15 dwmw2 Exp $
+ * $Id: blkmtd.c,v 1.23 2004/08/09 14:03:19 dwmw2 Exp $
*
* blkmtd.c - use a block device as a fake MTD
*
/* Default erase size in K, always make it a multiple of PAGE_SIZE */
#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
-#define VERSION "$Revision: 1.6 $"
+#define VERSION "$Revision: 1.23 $"
/* Info for the block device */
struct blkmtd_dev {
}
DEBUG(3, "blkmtd: erase: checking callback\n");
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
+ mtd_erase_callback(instr);
DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
return err;
}
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2000.c,v 1.60 2004/04/07 08:30:04 gleixner Exp $
+ * $Id: doc2000.c,v 1.62 2004/08/09 14:04:02 dwmw2 Exp $
*/
#include <linux/kernel.h>
instr->state = MTD_ERASE_DONE;
callback:
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
up(&this->lock);
return 0;
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001.c,v 1.42 2004/04/04 12:36:45 gleixner Exp $
+ * $Id: doc2001.c,v 1.44 2004/08/09 14:04:24 dwmw2 Exp $
*/
#include <linux/kernel.h>
instr->state = MTD_ERASE_DONE;
dummy = ReadDOC(docptr, LastDataRead);
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
*
- * $Id: doc2001plus.c,v 1.8 2004/04/04 12:36:45 gleixner Exp $
+ * $Id: doc2001plus.c,v 1.9 2004/08/09 13:19:44 dwmw2 Exp $
*
* Released under GPL
*/
/* Disable flash internally */
WriteDOC(0, docptr, Mplus_FlashSelect);
- if (instr->callback)
- instr->callback(instr);
+ mtd_erase_callback(instr);
return 0;
}
/*
* MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
*
- * $Id: lart.c,v 1.6 2004/07/14 17:21:38 dwmw2 Exp $
+ * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $
*
* Author: Abraham vd Merwe <abraham@2d3d.co.za>
*
}
instr->state = MTD_ERASE_DONE;
- if (instr->callback) instr->callback (instr);
+ mtd_erase_callback(instr);
return (0);
}
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * $Id: ms02-nv.c,v 1.6 2003/08/19 09:25:36 dwmw2 Exp $
+ * $Id: ms02-nv.c,v 1.7 2004/07/29 14:16:45 macro Exp $
*/
#include <linux/init.h>
static char version[] __initdata =
"ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n";
-MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
+MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
MODULE_LICENSE("GPL");
/*
* mtdram - a test mtd device
- * $Id: mtdram.c,v 1.32 2003/05/21 15:15:07 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.33 2004/08/09 13:19:44 dwmw2 Exp $
* Author: Alexander Larsson <alex@cendio.se>
*
* Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
- if (instr->callback)
- (*(instr->callback))(instr);
return 0;
}
/**
*
- * $Id: phram.c,v 1.1 2003/08/21 17:52:30 joern Exp $
+ * $Id: phram.c,v 1.2 2004/08/09 13:19:44 dwmw2 Exp $
*
* Copyright (c) Jochen Schaeuble <psionic@psionic.de>
* 07/2003 rewritten by Joern Engel <joern@wh.fh-wedel.de>
instr->state = MTD_ERASE_DONE;
- if (instr->callback)
- (*(instr->callback))(instr);
- else
- kfree(instr);
+ mtd_erase_callback(instr);
return 0;
}
/*
- * $Id: pmc551.c,v 1.27 2004/07/20 02:44:26 dwmw2 Exp $
+ * $Id: pmc551.c,v 1.28 2004/08/09 13:19:44 dwmw2 Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
printk(KERN_DEBUG "pmc551_erase() done\n");
#endif
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
+ mtd_erase_callback(instr);
return 0;
}
/*======================================================================
- $Id: slram.c,v 1.30 2003/05/20 21:03:08 dwmw2 Exp $
+ $Id: slram.c,v 1.31 2004/08/09 13:19:44 dwmw2 Exp $
This driver provides a method to access memory not used by the kernel
itself (i.e. if the kernel commandline mem=xxx is used). To actually
instr->state = MTD_ERASE_DONE;
- if (instr->callback) {
- (*(instr->callback))(instr);
- }
- else {
- kfree(instr);
- }
+ mtd_erase_callback(instr);
return(0);
}
/* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $
+ * $Id: ftl.c,v 1.53 2004/08/09 13:55:43 dwmw2 Exp $
*
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
int init_ftl(void)
{
- DEBUG(0, "$Id: ftl.c,v 1.52 2003/08/11 09:00:44 dwmw2 Exp $\n");
+ DEBUG(0, "$Id: ftl.c,v 1.53 2004/08/09 13:55:43 dwmw2 Exp $\n");
return register_mtd_blktrans(&ftl_tr);
}
* (c) 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org>
*
- * $Id: inftlcore.c,v 1.16 2004/07/12 12:34:58 dwmw2 Exp $
+ * $Id: inftlcore.c,v 1.17 2004/08/09 13:56:48 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
int __init init_inftl(void)
{
- printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.16 $, "
+ printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.17 $, "
"inftlmount.c %s\n", inftlmountrev);
return register_mtd_blktrans(&inftl_tr);
* Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A.
*
- * $Id: inftlmount.c,v 1.13 2004/06/28 16:06:36 dbrown Exp $
+ * $Id: inftlmount.c,v 1.14 2004/08/09 13:57:42 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h>
-char inftlmountrev[]="$Revision: 1.13 $";
+char inftlmountrev[]="$Revision: 1.14 $";
/*
* find_boot_record: Find the INFTL Media Header and its Spare copy which
# drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.29 2004/07/15 15:29:17 dwmw2 Exp $
+# $Id: Kconfig,v 1.30 2004/07/21 00:16:14 jwboyer Exp $
menu "Mapping drivers for chip access"
depends on MTD!=n
command set driver code to communicate with flash chips which
are mapped physically into the CPU's memory. You will need to
configure the physical address and size of the flash chips on
- your particular board as well as the bus width.
+ your particular board as well as the bus width, either statically
+ with config options or at run-time.
config MTD_PHYSMAP_START
hex "Physical start address of flash mapping"
are mapped on your particular target board. Refer to the
memory map which should hopefully be in the documentation for
your board.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
config MTD_PHYSMAP_LEN
hex "Physical length of flash mapping"
than the total amount of flash present. Refer to the memory
map which should hopefully be in the documentation for your
board.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
-config MTD_PHYSMAP_BUSWIDTH
- int "Bus width in octets"
+config MTD_PHYSMAP_BANKWIDTH
+ int "Bank width in octets"
depends on MTD_PHYSMAP
default "2"
help
in octets. For example, if you have a data bus width of 32
bits, you would set the bus width octect value to 4. This is
used internally by the CFI drivers.
+ Ignore this option if you use run-time physmap configuration
+ (i.e., run-time calling physmap_configure()).
config MTD_SUN_UFLASH
tristate "Sun Microsystems userflash support"
* ichxrom.c
*
* Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.7 2004/07/14 18:14:09 eric Exp $
+ * $Id: ichxrom.c,v 1.8 2004/07/16 17:43:11 dwmw2 Exp $
*/
#include <linux/module.h>
/*
- * $Id: physmap.c,v 1.33 2004/07/12 14:37:24 dwmw2 Exp $
+ * $Id: physmap.c,v 1.34 2004/07/21 00:16:14 jwboyer Exp $
*
* Normal mappings of chips in physical memory
*
static struct mtd_info *mymtd;
-struct map_info physmap_map = {.name = "phys_mapped_flash"};
+struct map_info physmap_map = {
+ .name = "phys_mapped_flash",
+ .phys = CONFIG_MTD_PHYSMAP_START,
+ .size = CONFIG_MTD_PHYSMAP_LEN,
+ .bankwidth = CONFIG_MTD_PHYSMAP_BANKWIDTH,
+};
#ifdef CONFIG_MTD_PARTITIONS
static struct mtd_partition *mtd_parts;
/*
- * $Id: mtdchar.c,v 1.62 2004/07/14 13:20:42 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.64 2004/08/09 13:59:46 dwmw2 Exp $
*
* Character-device access to raw MTD devices.
*
IOCTL calls for getting device parameters.
======================================================================*/
-static void mtd_erase_callback (struct erase_info *instr)
+static void mtdchar_erase_callback (struct erase_info *instr)
{
wake_up((wait_queue_head_t *)instr->priv);
}
return -EFAULT;
}
erase->mtd = mtd;
- erase->callback = mtd_erase_callback;
+ erase->callback = mtdchar_erase_callback;
erase->priv = (unsigned long)&waitq;
/*
}
default:
- DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %lx)\n", cmd, (unsigned long)MEMGETINFO);
ret = -ENOTTY;
}
*
* This code is GPL
*
- * $Id: mtdpart.c,v 1.46 2004/07/12 13:28:07 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.50 2004/08/10 16:18:34 dwmw2 Exp $
*
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob
return -EINVAL;
instr->addr += part->offset;
ret = part->master->erase(part->master, instr);
- if (instr->fail_addr != 0xffffffff)
- instr->fail_addr -= part->offset;
return ret;
}
+void mtd_erase_callback(struct erase_info *instr)
+{
+ if (instr->mtd->erase == part_erase) {
+ struct mtd_part *part = PART(instr->mtd);
+
+ if (instr->fail_addr != 0xffffffff)
+ instr->fail_addr -= part->offset;
+ instr->addr -= part->offset;
+ }
+ if (instr->callback)
+ instr->callback(instr);
+}
+EXPORT_SYMBOL_GPL(mtd_erase_callback);
+
static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
{
struct mtd_part *part = PART(mtd);
# drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.14 2004/07/13 00:14:35 dbrown Exp $
+# $Id: Kconfig,v 1.17 2004/08/10 14:24:07 dwmw2 Exp $
menu "NAND Flash Device Drivers"
depends on MTD!=n
This enables the NAND flash driver on the PPChameleon EVB Board.
config MTD_NAND_DISKONCHIP
- tristate "DiskOnChip 2000 and Millennium (NAND reimplementation) (EXPERIMENTAL)"
+ tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
depends on MTD_NAND && EXPERIMENTAL
help
- This is a reimplementation of M-Systems DiskOnChip 2000 and
- Millennium as a standard NAND device driver, as opposed to the
- earlier self-contained MTD device drivers.
+ This is a reimplementation of M-Systems DiskOnChip 2000,
+ Millennium and Millennium Plus as a standard NAND device driver,
+ as opposed to the earlier self-contained MTD device drivers.
This should enable, among other things, proper JFFS2 operation on
these devices.
+config MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ bool "Advanced detection options for DiskOnChip"
+ depends on MTD_NAND_DISKONCHIP
+ help
+ This option allows you to specify nonstandard address at which to
+ probe for a DiskOnChip, or to change the detection options. You
+ are unlikely to need any of this unless you are using LinuxBIOS.
+ Say 'N'.
+
+config MTD_NAND_DISKONCHIP_PROBE_ADDRESS
+ hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ depends on MTD_NAND_DISKONCHIP
+ default "0"
+ ---help---
+ By default, the probe for DiskOnChip devices will look for a
+ DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+ This option allows you to specify a single address at which to probe
+ for the device, which is useful if you have other devices in that
+ range which get upset when they are probed.
+
+ (Note that on PowerPC, the normal probe will only check at
+ 0xE4000000.)
+
+ Normally, you should leave this set to zero, to allow the probe at
+ the normal addresses.
+
+config MTD_NAND_DISKONCHIP_PROBE_HIGH
+ bool "Probe high addresses"
+ depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED
+ help
+ By default, the probe for DiskOnChip devices will look for a
+ DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000.
+ This option changes to make it probe between 0xFFFC8000 and
+ 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be
+ useful to you. Say 'N'.
+
config MTD_NAND_DISKONCHIP_BBTWRITE
bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP"
depends on MTD_NAND_DISKONCHIP
* drivers/mtd/nand/diskonchip.c
*
* (C) 2003 Red Hat, Inc.
+ * (C) 2004 Dan Brown <dan_brown@ieee.org>
+ * (C) 2004 Kalev Lember <kalev@smartlink.ee>
*
* Author: David Woodhouse <dwmw2@infradead.org>
+ * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
+ * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
*
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
- * $Id: diskonchip.c,v 1.25 2004/07/16 13:54:27 dbrown Exp $
+ * $Id: diskonchip.c,v 1.34 2004/08/09 19:41:12 dbrown Exp $
*/
#include <linux/kernel.h>
#include <linux/mtd/inftl.h>
/* Where to look for the devices? */
-#ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-#define CONFIG_MTD_DOCPROBE_ADDRESS 0
+#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
+#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
#endif
static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DOCPROBE_HIGH
+#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
#define INFTL_BBT_RESERVED_BLOCKS 4
+#define DoC_is_MillenniumPlus(doc) ((doc)->ChipID == DOC_ChipID_DocMilPlus16 || (doc)->ChipID == DOC_ChipID_DocMilPlus32)
#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
#endif
MODULE_PARM(inftl_bbt_write, "i");
-static unsigned long doc_config_location = CONFIG_MTD_DOCPROBE_ADDRESS;
+static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
MODULE_PARM(doc_config_location, "l");
MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP);
+ else if (DoC_is_MillenniumPlus(doc))
+ dummy = ReadDOC(doc->virtadr, Mplus_NOP);
else
dummy = ReadDOC(doc->virtadr, DOCStatus);
}
}
+
+#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
+
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
static int _DoC_WaitReady(struct doc_priv *doc)
{
if(debug) printk("_DoC_WaitReady...\n");
/* Out-of-line routine to wait for chip response */
- while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
- if (time_after(jiffies, timeo)) {
- printk("_DoC_WaitReady timed out.\n");
- return -EIO;
+ if (DoC_is_MillenniumPlus(doc)) {
+ while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+ if (time_after(jiffies, timeo)) {
+ printk("_DoC_WaitReady timed out.\n");
+ return -EIO;
+ }
+ udelay(1);
+ cond_resched();
+ }
+ } else {
+ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+ if (time_after(jiffies, timeo)) {
+ printk("_DoC_WaitReady timed out.\n");
+ return -EIO;
+ }
+ udelay(1);
+ cond_resched();
}
- udelay(1);
- cond_resched();
}
return 0;
unsigned long docptr = doc->virtadr;
int ret = 0;
- DoC_Delay(doc, 4);
+ if (DoC_is_MillenniumPlus(doc)) {
+ DoC_Delay(doc, 4);
- if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
- /* Call the out-of-line routine to wait */
- ret = _DoC_WaitReady(doc);
+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(doc);
+ } else {
+ DoC_Delay(doc, 4);
+
+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
+ /* Call the out-of-line routine to wait */
+ ret = _DoC_WaitReady(doc);
+ DoC_Delay(doc, 2);
+ }
- DoC_Delay(doc, 2);
if(debug) printk("DoC_WaitReady OK\n");
return ret;
}
return 0;
}
-static void doc200x_select_chip(struct mtd_info *mtd, int chip)
+static u_char doc2001plus_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ u_char ret;
+
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ret = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug) printk("read_byte returns %02x\n", ret);
+ return ret;
+}
+
+static void doc2001plus_writebuf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("writebuf of %d bytes: ", len);
+ for (i=0; i < len; i++) {
+ WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
+ if (debug && i < 16)
+ printk("%02x ", buf[i]);
+ }
+ if (debug) printk("\n");
+}
+
+static void doc2001plus_readbuf(struct mtd_info *mtd,
+ u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("readbuf of %d bytes: ", len);
+
+ /* Start read pipeline */
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+
+ for (i=0; i < len-2; i++) {
+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
+ if (debug && i < 16)
+ printk("%02x ", buf[i]);
+ }
+
+ /* Terminate read pipeline */
+ buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug && i < 16)
+ printk("%02x ", buf[len-2]);
+ buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
+ if (debug && i < 16)
+ printk("%02x ", buf[len-1]);
+ if (debug) printk("\n");
+}
+
+static int doc2001plus_verifybuf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int i;
+
+ if (debug)printk("verifybuf of %d bytes: ", len);
+
+ /* Start read pipeline */
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+ ReadDOC(docptr, Mplus_ReadPipeInit);
+
+ for (i=0; i < len-2; i++)
+ if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
+ ReadDOC(docptr, Mplus_LastDataRead);
+ ReadDOC(docptr, Mplus_LastDataRead);
+ return i;
+ }
+ if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead))
+ return len-2;
+ if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead))
+ return len-1;
+ return 0;
+}
+
+static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
unsigned long docptr = doc->virtadr;
int floor = 0;
- /* 11.4.4 -- deassert CE before changing chip */
- doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
+ if(debug)printk("select chip (%d)\n", chip);
+
+ if (chip == -1) {
+ /* Disable flash internally */
+ WriteDOC(0, docptr, Mplus_FlashSelect);
+ return;
+ }
+
+ floor = chip / doc->chips_per_floor;
+ chip -= (floor * doc->chips_per_floor);
+
+ /* Assert ChipEnable and deassert WriteProtect */
+ WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect);
+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+ doc->curchip = chip;
+ doc->curfloor = floor;
+}
+
+static void doc200x_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+ int floor = 0;
if(debug)printk("select chip (%d)\n", chip);
floor = chip / doc->chips_per_floor;
chip -= (floor * doc->chips_per_floor);
+ /* 11.4.4 -- deassert CE before changing chip */
+ doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
+
WriteDOC(floor, docptr, FloorSelect);
WriteDOC(chip, docptr, CDSNDeviceSelect);
DoC_Delay(doc, 4);
}
+static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+
+ /*
+ * Must terminate write pipeline before sending any commands
+ * to the device.
+ */
+ if (command == NAND_CMD_PAGEPROG) {
+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
+ }
+
+ /*
+ * Write out the command to the device.
+ */
+ if (command == NAND_CMD_SEQIN) {
+ int readcmd;
+
+ if (column >= mtd->oobblock) {
+ /* OOB area */
+ column -= mtd->oobblock;
+ readcmd = NAND_CMD_READOOB;
+ } else if (column < 256) {
+ /* First 256 bytes --> READ0 */
+ readcmd = NAND_CMD_READ0;
+ } else {
+ column -= 256;
+ readcmd = NAND_CMD_READ1;
+ }
+ WriteDOC(readcmd, docptr, Mplus_FlashCmd);
+ }
+ WriteDOC(command, docptr, Mplus_FlashCmd);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+
+ if (column != -1 || page_addr != -1) {
+ /* Serially input address */
+ if (column != -1) {
+ /* Adjust columns for 16 bit buswidth */
+ if (this->options & NAND_BUSWIDTH_16)
+ column >>= 1;
+ WriteDOC(column, docptr, Mplus_FlashAddress);
+ }
+ if (page_addr != -1) {
+ WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress);
+ WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress);
+ /* One more address cycle for higher density devices */
+ if (this->chipsize & 0x0c000000) {
+ WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress);
+ printk("high density\n");
+ }
+ }
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ /* deassert ALE */
+ if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID)
+ WriteDOC(0, docptr, Mplus_FlashControl);
+ }
+
+ /*
+ * program and erase have their own busy handlers
+ * status and sequential in needs no delay
+ */
+ switch (command) {
+
+ case NAND_CMD_PAGEPROG:
+ case NAND_CMD_ERASE1:
+ case NAND_CMD_ERASE2:
+ case NAND_CMD_SEQIN:
+ case NAND_CMD_STATUS:
+ return;
+
+ case NAND_CMD_RESET:
+ if (this->dev_ready)
+ break;
+ udelay(this->chip_delay);
+ WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ WriteDOC(0, docptr, Mplus_WritePipeTerm);
+ while ( !(this->read_byte(mtd) & 0x40));
+ return;
+
+ /* This applies to read commands */
+ default:
+ /*
+ * If we don't have access to the busy pin, we apply the given
+ * command delay
+ */
+ if (!this->dev_ready) {
+ udelay (this->chip_delay);
+ return;
+ }
+ }
+
+ /* Apply this short delay always to ensure that we do wait tWB in
+ * any case on any machine. */
+ ndelay (100);
+ /* wait until command is processed */
+ while (!this->dev_ready(mtd));
+}
+
static int doc200x_dev_ready(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
unsigned long docptr = doc->virtadr;
- /* 11.4.2 -- must NOP four times before checking FR/B# */
- DoC_Delay(doc, 4);
- if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
- if(debug)
- printk("not ready\n");
- return 0;
+ if (DoC_is_MillenniumPlus(doc)) {
+ /* 11.4.2 -- must NOP four times before checking FR/B# */
+ DoC_Delay(doc, 4);
+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) {
+ if(debug)
+ printk("not ready\n");
+ return 0;
+ }
+ if (debug)printk("was ready\n");
+ return 1;
+ } else {
+ /* 11.4.2 -- must NOP four times before checking FR/B# */
+ DoC_Delay(doc, 4);
+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
+ if(debug)
+ printk("not ready\n");
+ return 0;
+ }
+ /* 11.4.2 -- Must NOP twice if it's ready */
+ DoC_Delay(doc, 2);
+ if (debug)printk("was ready\n");
+ return 1;
}
- /* 11.4.2 -- Must NOP twice if it's ready */
- DoC_Delay(doc, 2);
- if (debug)printk("was ready\n");
- return 1;
-}
+}
static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
{
WriteDOC(DOC_ECC_RESET, docptr, ECCConf);
WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
break;
- }
+ }
+}
+
+static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+ unsigned long docptr = doc->virtadr;
+
+ /* Prime the ECC engine */
+ switch(mode) {
+ case NAND_ECC_READ:
+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+ WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
+ break;
+ case NAND_ECC_WRITE:
+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
+ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
+ break;
+ }
}
/* This code is only called on write */
WriteDOC(0, docptr, 2k_CDSN_IO);
WriteDOC(0, docptr, 2k_CDSN_IO);
WriteDOC(doc->CDSNControl, docptr, CDSNControl);
+ } else if (DoC_is_MillenniumPlus(doc)) {
+ WriteDOC(0, docptr, Mplus_NOP);
+ WriteDOC(0, docptr, Mplus_NOP);
+ WriteDOC(0, docptr, Mplus_NOP);
} else {
WriteDOC(0, docptr, NOP);
WriteDOC(0, docptr, NOP);
}
for (i = 0; i < 6; i++) {
- ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+ if (DoC_is_MillenniumPlus(doc))
+ ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+ else
+ ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (ecc_code[i] != empty_write_ecc[i])
emptymatch = 0;
}
- WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ if (DoC_is_MillenniumPlus(doc))
+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+ else
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
#if 0
/* If emptymatch=1, we might have an all-0xff data buffer. Check. */
if (emptymatch) {
dummy = ReadDOC(docptr, 2k_ECCStatus);
dummy = ReadDOC(docptr, 2k_ECCStatus);
dummy = ReadDOC(docptr, 2k_ECCStatus);
+ } else if (DoC_is_MillenniumPlus(doc)) {
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
+ dummy = ReadDOC(docptr, Mplus_ECCConf);
} else {
dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf);
/* Error occured ? */
if (dummy & 0x80) {
for (i = 0; i < 6; i++) {
- calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
+ if (DoC_is_MillenniumPlus(doc))
+ calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
+ else
+ calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (calc_ecc[i] != empty_read_syndrome[i])
emptymatch = 0;
}
if (ret > 0)
printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
}
- WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
+ if (DoC_is_MillenniumPlus(doc))
+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
+ else
+ WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
if (no_ecc_failures && (ret == -1)) {
printk(KERN_ERR "suppressing ECC failure\n");
ret = 0;
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
- u_char *buf = this->data_buf;
- struct NFTLMediaHeader *mh = (struct NFTLMediaHeader *) buf;
+ int ret = 0;
+ u_char *buf;
+ struct NFTLMediaHeader *mh;
const unsigned psize = 1 << this->page_shift;
unsigned blocks, maxblocks;
int offs, numheaders;
- if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) return 0;
+ buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+ return 0;
+ }
+ if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
+ mh = (struct NFTLMediaHeader *) buf;
//#ifdef CONFIG_MTD_DEBUG_VERBOSE
// if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
if (blocks > maxblocks) {
printk(KERN_ERR "UnitSizeFactor of 0x%02x is inconsistent with device size. Aborting.\n", mh->UnitSizeFactor);
- return 0;
+ goto out;
}
/* Skip past the media headers. */
parts[1].name = " DiskOnChip Remainder partition";
parts[1].offset = offs;
parts[1].size = mtd->size - offs;
- return 2;
+ ret = 2;
+ goto out;
}
- return 1;
+ ret = 1;
+out:
+ kfree(buf);
+ return ret;
}
/* This is a stripped-down copy of the code in inftlmount.c */
{
struct nand_chip *this = mtd->priv;
struct doc_priv *doc = (void *)this->priv;
- u_char *buf = this->data_buf;
- struct INFTLMediaHeader *mh = (struct INFTLMediaHeader *) buf;
+ int ret = 0;
+ u_char *buf;
+ struct INFTLMediaHeader *mh;
struct INFTLPartition *ip;
int numparts = 0;
int blocks;
if (inftl_bbt_write)
end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift);
- if (!find_media_headers(mtd, buf, "BNAND", 0)) return 0;
+ buf = kmalloc(mtd->oobblock, GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
+ return 0;
+ }
+
+ if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out;
doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift);
+ mh = (struct INFTLMediaHeader *) buf;
mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
" NoOfBDTLPartitions = %d\n"
" BlockMultiplerBits = %d\n"
" FormatFlgs = %d\n"
- " OsakVersion = 0x%x\n"
+ " OsakVersion = %d.%d.%d.%d\n"
" PercentUsed = %d\n",
mh->bootRecordID, mh->NoOfBootImageBlocks,
mh->NoOfBinaryPartitions,
mh->NoOfBDTLPartitions,
mh->BlockMultiplierBits, mh->FormatFlags,
- mh->OsakVersion, mh->PercentUsed);
+ ((unsigned char *) &mh->OsakVersion)[0] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[1] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[2] & 0xf,
+ ((unsigned char *) &mh->OsakVersion)[3] & 0xf,
+ mh->PercentUsed);
//#endif
vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
blocks = mtd->size >> vshift;
if (blocks > 32768) {
printk(KERN_ERR "BlockMultiplierBits=%d is inconsistent with device size. Aborting.\n", mh->BlockMultiplierBits);
- return 0;
+ goto out;
}
blocks = doc->chips_per_floor << (this->chip_shift - this->phys_erase_shift);
if (inftl_bbt_write && (blocks > mtd->erasesize)) {
printk(KERN_ERR "Writeable BBTs spanning more than one erase block are not yet supported. FIX ME!\n");
- return 0;
+ goto out;
}
/* Scan the partitions */
parts[numparts].size = end - parts[numparts].offset;
numparts++;
}
- return numparts;
+ ret = numparts;
+out:
+ kfree(buf);
+ return ret;
}
static int __init nftl_scan_bbt(struct mtd_info *mtd)
if ((ret = nand_scan_bbt(mtd, NULL)))
return ret;
add_mtd_device(mtd);
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- if (!no_autopart) add_mtd_partitions(mtd, parts, numparts);
+#ifdef CONFIG_MTD_PARTITIONS
+ if (!no_autopart)
+ add_mtd_partitions(mtd, parts, numparts);
#endif
return 0;
}
return -EIO;
}
- this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
- NAND_BBT_VERSION;
- if (inftl_bbt_write)
- this->bbt_td->options |= NAND_BBT_WRITE;
- this->bbt_td->offs = 8;
- this->bbt_td->len = 8;
- this->bbt_td->veroffs = 7;
- this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
- this->bbt_td->reserved_block_code = 0x01;
- this->bbt_td->pattern = "MSYS_BBT";
-
- this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
- NAND_BBT_VERSION;
- if (inftl_bbt_write)
- this->bbt_md->options |= NAND_BBT_WRITE;
- this->bbt_md->offs = 8;
- this->bbt_md->len = 8;
- this->bbt_md->veroffs = 7;
- this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
- this->bbt_md->reserved_block_code = 0x01;
- this->bbt_md->pattern = "TBB_SYSM";
+ if (DoC_is_MillenniumPlus(doc)) {
+ this->bbt_td->options = NAND_BBT_2BIT | NAND_BBT_ABSPAGE;
+ if (inftl_bbt_write)
+ this->bbt_td->options |= NAND_BBT_WRITE;
+ this->bbt_td->pages[0] = 2;
+ this->bbt_md = NULL;
+ } else {
+ this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+ NAND_BBT_VERSION;
+ if (inftl_bbt_write)
+ this->bbt_td->options |= NAND_BBT_WRITE;
+ this->bbt_td->offs = 8;
+ this->bbt_td->len = 8;
+ this->bbt_td->veroffs = 7;
+ this->bbt_td->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+ this->bbt_td->reserved_block_code = 0x01;
+ this->bbt_td->pattern = "MSYS_BBT";
+
+ this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT |
+ NAND_BBT_VERSION;
+ if (inftl_bbt_write)
+ this->bbt_md->options |= NAND_BBT_WRITE;
+ this->bbt_md->offs = 8;
+ this->bbt_md->len = 8;
+ this->bbt_md->veroffs = 7;
+ this->bbt_md->maxblocks = INFTL_BBT_RESERVED_BLOCKS;
+ this->bbt_md->reserved_block_code = 0x01;
+ this->bbt_md->pattern = "TBB_SYSM";
+ }
/* It's safe to set bd=NULL below because NAND_BBT_CREATE is not set.
At least as nand_bbt.c is currently written. */
autopartitioning, but I want to give it more thought. */
if (!numparts) return -EIO;
add_mtd_device(mtd);
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- if (!no_autopart) add_mtd_partitions(mtd, parts, numparts);
+#ifdef CONFIG_MTD_PARTITIONS
+ if (!no_autopart)
+ add_mtd_partitions(mtd, parts, numparts);
#endif
return 0;
}
}
}
+static inline int __init doc2001plus_init(struct mtd_info *mtd)
+{
+ struct nand_chip *this = mtd->priv;
+ struct doc_priv *doc = (void *)this->priv;
+
+ this->write_byte = NULL;
+ this->read_byte = doc2001plus_read_byte;
+ this->write_buf = doc2001plus_writebuf;
+ this->read_buf = doc2001plus_readbuf;
+ this->verify_buf = doc2001plus_verifybuf;
+ this->scan_bbt = inftl_scan_bbt;
+ this->hwcontrol = NULL;
+ this->select_chip = doc2001plus_select_chip;
+ this->cmdfunc = doc2001plus_command;
+ this->enable_hwecc = doc2001plus_enable_hwecc;
+
+ doc->chips_per_floor = 1;
+ mtd->name = "DiskOnChip Millennium Plus";
+
+ return 1;
+}
+
static inline int __init doc_probe(unsigned long physadr)
{
unsigned char ChipID;
case DOC_ChipID_DocMil:
reg = DoC_ECCConf;
break;
+ case DOC_ChipID_DocMilPlus16:
+ case DOC_ChipID_DocMilPlus32:
+ case 0:
+ /* Possible Millennium Plus, need to do more checks */
+ /* Possibly release from power down mode */
+ for (tmp = 0; (tmp < 4); tmp++)
+ ReadDOC(virtadr, Mplus_Power);
+
+ /* Reset the Millennium Plus ASIC */
+ tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+ DOC_MODE_BDECT;
+ WriteDOC(tmp, virtadr, Mplus_DOCControl);
+ WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+
+ mdelay(1);
+ /* Enable the Millennium Plus ASIC */
+ tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
+ DOC_MODE_BDECT;
+ WriteDOC(tmp, virtadr, Mplus_DOCControl);
+ WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm);
+ mdelay(1);
+
+ ChipID = ReadDOC(virtadr, ChipID);
+
+ switch (ChipID) {
+ case DOC_ChipID_DocMilPlus16:
+ reg = DoC_Mplus_Toggle;
+ break;
+ case DOC_ChipID_DocMilPlus32:
+ printk(KERN_ERR "DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n");
+ default:
+ ret = -ENODEV;
+ goto notfound;
+ }
+ break;
+
default:
ret = -ENODEV;
goto notfound;
in fact the same DOC aliased to a new address. If writes
to one chip's alias resolution register change the value on
the other chip, they're the same chip. */
- oldval = ReadDOC(doc->virtadr, AliasResolution);
- newval = ReadDOC(virtadr, AliasResolution);
+ if (ChipID == DOC_ChipID_DocMilPlus16) {
+ oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+ newval = ReadDOC(virtadr, Mplus_AliasResolution);
+ } else {
+ oldval = ReadDOC(doc->virtadr, AliasResolution);
+ newval = ReadDOC(virtadr, AliasResolution);
+ }
if (oldval != newval)
continue;
- WriteDOC(~newval, virtadr, AliasResolution);
- oldval = ReadDOC(doc->virtadr, AliasResolution);
- WriteDOC(newval, virtadr, AliasResolution); // restore it
+ if (ChipID == DOC_ChipID_DocMilPlus16) {
+ WriteDOC(~newval, virtadr, Mplus_AliasResolution);
+ oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution);
+ WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it
+ } else {
+ WriteDOC(~newval, virtadr, AliasResolution);
+ oldval = ReadDOC(doc->virtadr, AliasResolution);
+ WriteDOC(newval, virtadr, AliasResolution); // restore it
+ }
newval = ~newval;
if (oldval == newval) {
- //printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
+ printk(KERN_DEBUG "Found alias of DOC at 0x%lx to 0x%lx\n", doc->physadr, physadr);
goto notfound;
}
}
if (ChipID == DOC_ChipID_Doc2k)
numchips = doc2000_init(mtd);
+ else if (ChipID == DOC_ChipID_DocMilPlus16)
+ numchips = doc2001plus_init(mtd);
else
numchips = doc2001_init(mtd);
kfree(mtd);
}
}
-
+
module_init(init_nanddoc);
module_exit(cleanup_nanddoc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000 and Millennium device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
* The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go.
*
- * $Id: nand_base.c,v 1.113 2004/07/14 16:31:31 gleixner Exp $
+ * $Id: nand_base.c,v 1.115 2004/08/09 13:19:45 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#include <linux/bitops.h>
#include <asm/io.h>
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
+#ifdef CONFIG_MTD_PARTITIONS
#include <linux/mtd/partitions.h>
#endif
nand_release_chip(mtd);
/*
- * Return success, if no ECC failures, else -EIO
+ * Return success, if no ECC failures, else -EBADMSG
* fs driver will take care of that, because
- * retlen == desired len and result == -EIO
+ * retlen == desired len and result == -EBADMSG
*/
*retlen = read;
- return ecc_failed ? -EIO : 0;
+ return ecc_failed ? -EBADMSG : 0;
}
/**
ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
/* Do call back function */
- if (!ret && instr->callback)
- instr->callback (instr);
+ if (!ret)
+ mtd_erase_callback(instr);
/* Deselect and wake up anyone waiting on the device */
nand_release_chip(mtd);
{
struct nand_chip *this = mtd->priv;
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
- /* Unregister partitions */
+#ifdef CONFIG_MTD_PARTITIONS
+ /* Deregister partitions */
del_mtd_partitions (mtd);
#endif
- /* Unregister the device */
+ /* Deregister the device */
del_mtd_device (mtd);
/* Free bad block table memory, if allocated */
/*
- * $Id: redboot.c,v 1.13 2004/04/01 10:17:40 gthomas Exp $
+ * $Id: redboot.c,v 1.15 2004/08/10 07:55:16 dwmw2 Exp $
*
* Parse RedBoot-style Flash Image System (FIS) tables and
* produce a Linux partition array to match.
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
static char nullstring[] = "unallocated";
#endif
- buf = kmalloc(master->erasesize, GFP_KERNEL);
+ buf = vmalloc(master->erasesize);
if (!buf)
return -ENOMEM;
fl = fl->next;
kfree(old);
}
- kfree(buf);
+ vfree(buf);
return ret;
}
}
/* Set the wrap registers for string I/O reads. */
- outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
+ outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
/* Set the base address to point to the NIC, not the "real" base! */
dev->base_addr = ioaddr + NIC_OFFSET;
ei_status.name = name;
ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */
ei_status.tx_start_page = HP_START_PG;
- ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
+ ei_status.rx_start_page = HP_START_PG + TX_PAGES/2;
ei_status.stop_page = HP_STOP_PG;
ei_status.reset_8390 = &hpp_reset_8390;
ei_status.block_output = &hpp_mem_block_output;
ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr;
dev->mem_start = mem_start;
- ei_status.rmem_start = dev->mem_start + TX_2X_PAGES*256;
+ ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256;
dev->mem_end = ei_status.rmem_end
= dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
}
/* Set the wrap registers for programmed-I/O operation. */
outw(HW_Page, ioaddr + HP_PAGING);
- outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
+ outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
/* Select the operational page. */
outw(Perf_Page, ioaddr + HP_PAGING);
#include <asm/cache.h>
#include <asm/parisc-device.h>
-static char version[] __devinitdata =
- "82596.c $Revision: 1.29 $\n";
+#define LASI_82596_DRIVER_VERSION "LASI 82596 driver - Revision: 1.30"
/* DEBUG flags
*/
do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0)
#define CHECK_INV(addr,len) \
- do { dma_cache_sync((void *)addr,len, DMA_FROM_DEVICE); } while(0)
+ do { dma_cache_sync((void *)addr, len, DMA_FROM_DEVICE); } while(0)
#define CHECK_WBACK_INV(addr,len) \
- do { dma_cache_sync((void *)addr,len, DMA_BIDIRECTIONAL); } while (0)
+ do { dma_cache_sync((void *)addr, len, DMA_BIDIRECTIONAL); } while (0)
#define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/
rfd = lp->rfd_head;
printk("rfd_head = %p\n", rfd);
do {
- printk (" %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
+ printk(" %p .stat %04x, .cmd %04x, b_next %08x, rbd %08x,"
" count %04x\n",
rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
rfd->count);
struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ + 4);
if (skb == NULL)
- panic("82596: alloc_skb() failed");
+ panic("%s: alloc_skb() failed", __FILE__);
skb_reserve(skb, 2);
dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
DMA_FROM_DEVICE);
disable_irq(dev->irq); /* disable IRQs from LAN */
DEB(DEB_INIT,
- printk("RESET 82596 port: %08lX (with IRQ%d disabled)\n",
- dev->base_addr + PA_I82596_RESET,
+ printk("RESET 82596 port: %p (with IRQ %d disabled)\n",
+ (void*)(dev->base_addr + PA_I82596_RESET),
dev->irq));
gsc_writel(0, (void*)(dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
lp->cmd_head = NULL;
lp->scb.cmd = I596_NULL;
- DEB(DEB_INIT,printk("%s: starting i82596.\n", dev->name));
+ DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name));
CHECK_WBACK(&(lp->scp), sizeof(struct i596_scp));
CHECK_WBACK(&(lp->iscp), sizeof(struct i596_iscp));
CA(dev);
- if (wait_istat(dev,lp,1000,"initialization timed out"))
+ if (wait_istat(dev, lp, 1000, "initialization timed out"))
goto failed;
- DEB(DEB_INIT,printk("%s: i82596 initialization successful\n", dev->name));
+ DEB(DEB_INIT, printk("%s: i82596 initialization successful\n", dev->name));
/* Ensure rx frame/buffer descriptors are tidy */
rebuild_rx_bufs(dev);
enable_irq(dev->irq); /* enable IRQs from LAN */
- DEB(DEB_INIT,printk("%s: queuing CmdConfigure\n", dev->name));
+ DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name));
memcpy(lp->cf_cmd.i596_config, init_setup, 14);
lp->cf_cmd.cmd.command = CmdConfigure;
CHECK_WBACK(&(lp->cf_cmd), sizeof(struct cf_cmd));
i596_add_cmd(dev, &lp->cf_cmd.cmd);
- DEB(DEB_INIT,printk("%s: queuing CmdSASetup\n", dev->name));
+ DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name));
memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
lp->sa_cmd.cmd.command = CmdSASetup;
CHECK_WBACK(&(lp->sa_cmd), sizeof(struct sa_cmd));
i596_add_cmd(dev, &lp->sa_cmd.cmd);
- DEB(DEB_INIT,printk("%s: queuing CmdTDR\n", dev->name));
+ DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name));
lp->tdr_cmd.cmd.command = CmdTDR;
CHECK_WBACK(&(lp->tdr_cmd), sizeof(struct tdr_cmd));
i596_add_cmd(dev, &lp->tdr_cmd.cmd);
spin_lock_irqsave (&lp->lock, flags);
- if (wait_cmd(dev,lp,1000,"timed out waiting to issue RX_START")) {
+ if (wait_cmd(dev, lp, 1000, "timed out waiting to issue RX_START")) {
spin_unlock_irqrestore (&lp->lock, flags);
goto failed;
}
- DEB(DEB_INIT,printk("%s: Issuing RX_START\n", dev->name));
+ DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name));
lp->scb.command = RX_START;
lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds));
CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
spin_unlock_irqrestore (&lp->lock, flags);
- if (wait_cmd(dev,lp,1000,"RX_START not processed"))
+ if (wait_cmd(dev, lp, 1000, "RX_START not processed"))
goto failed;
- DEB(DEB_INIT,printk("%s: Receive unit started OK\n", dev->name));
+ DEB(DEB_INIT, printk("%s: Receive unit started OK\n", dev->name));
return 0;
struct i596_rbd *rbd;
int frames = 0;
- DEB(DEB_RXFRAME,printk ("i596_rx(), rfd_head %p, rbd_head %p\n",
+ DEB(DEB_RXFRAME, printk("i596_rx(), rfd_head %p, rbd_head %p\n",
lp->rfd_head, lp->rbd_head));
memory_squeeze:
if (skb == NULL) {
/* XXX tulip.c can defer packets here!! */
- printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
+ printk("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
lp->stats.rx_dropped++;
}
else {
CHECK_INV(rfd, sizeof(struct i596_rfd));
}
- DEB(DEB_RXFRAME,printk ("frames %d\n", frames));
+ DEB(DEB_RXFRAME, printk("frames %d\n", frames));
return 0;
}
CHECK_WBACK_INV(ptr, sizeof(struct i596_cmd));
}
- wait_cmd(dev,lp,100,"i596_cleanup_cmd timed out");
+ wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out");
lp->scb.cmd = I596_NULL;
CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
}
{
unsigned long flags;
- DEB(DEB_RESET,printk("i596_reset\n"));
+ DEB(DEB_RESET, printk("i596_reset\n"));
spin_lock_irqsave (&lp->lock, flags);
- wait_cmd(dev,lp,100,"i596_reset timed out");
+ wait_cmd(dev, lp, 100, "i596_reset timed out");
netif_stop_queue(dev);
CA(dev);
/* wait for shutdown */
- wait_cmd(dev,lp,1000,"i596_reset 2 timed out");
+ wait_cmd(dev, lp, 1000, "i596_reset 2 timed out");
spin_unlock_irqrestore (&lp->lock, flags);
i596_cleanup_cmd(dev,lp);
struct i596_private *lp = dev->priv;
unsigned long flags;
- DEB(DEB_ADDCMD,printk("i596_add_cmd cmd_head %p\n", lp->cmd_head));
+ DEB(DEB_ADDCMD, printk("i596_add_cmd cmd_head %p\n", lp->cmd_head));
cmd->status = 0;
cmd->command |= (CMD_EOL | CMD_INTR);
CHECK_WBACK(lp->cmd_tail, sizeof(struct i596_cmd));
} else {
lp->cmd_head = cmd;
- wait_cmd(dev,lp,100,"i596_add_cmd timed out");
+ wait_cmd(dev, lp, 100, "i596_add_cmd timed out");
lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status));
lp->scb.command = CUC_START;
CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb));
static int i596_open(struct net_device *dev)
{
- DEB(DEB_OPEN,printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
+ DEB(DEB_OPEN, printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
printk("%s: IRQ %d not free\n", dev->name, dev->irq);
struct i596_private *lp = dev->priv;
/* Transmitter timeout, serious problems. */
- DEB(DEB_ERRORS,printk("%s: transmit timed out, status resetting.\n",
+ DEB(DEB_ERRORS, printk("%s: transmit timed out, status resetting.\n",
dev->name));
lp->stats.tx_errors++;
/* Try to restart the adaptor */
if (lp->last_restart == lp->stats.tx_packets) {
- DEB(DEB_ERRORS,printk ("Resetting board.\n"));
+ DEB(DEB_ERRORS, printk("Resetting board.\n"));
/* Shutdown and restart */
i596_reset (dev, lp);
} else {
/* Issue a channel attention signal */
- DEB(DEB_ERRORS,printk ("Kicking board.\n"));
+ DEB(DEB_ERRORS, printk("Kicking board.\n"));
lp->scb.command = CUC_START | RX_START;
CHECK_WBACK_INV(&(lp->scb), sizeof(struct i596_scb));
CA (dev);
short length = skb->len;
dev->trans_start = jiffies;
- DEB(DEB_STARTTX,printk("%s: i596_start_xmit(%x,%p) called\n", dev->name,
+ DEB(DEB_STARTTX, printk("%s: i596_start_xmit(%x,%p) called\n", dev->name,
skb->len, skb->data));
if (length < ETH_ZLEN) {
tbd = lp->tbds + lp->next_tx_cmd;
if (tx_cmd->cmd.command) {
- DEB(DEB_ERRORS,printk ("%s: xmit ring full, dropping packet.\n",
+ DEB(DEB_ERRORS, printk("%s: xmit ring full, dropping packet.\n",
dev->name));
lp->stats.tx_dropped++;
/* This lot is ensure things have been cache line aligned. */
if (sizeof(struct i596_rfd) != 32) {
printk("82596: sizeof(struct i596_rfd) = %d\n",
- sizeof(struct i596_rfd));
+ (int)sizeof(struct i596_rfd));
return -ENODEV;
}
if ((sizeof(struct i596_rbd) % 32) != 0) {
printk("82596: sizeof(struct i596_rbd) = %d\n",
- sizeof(struct i596_rbd));
+ (int)sizeof(struct i596_rbd));
return -ENODEV;
}
if ((sizeof(struct tx_cmd) % 32) != 0) {
printk("82596: sizeof(struct tx_cmd) = %d\n",
- sizeof(struct tx_cmd));
+ (int)sizeof(struct tx_cmd));
return -ENODEV;
}
if (sizeof(struct i596_tbd) != 32) {
printk("82596: sizeof(struct i596_tbd) = %d\n",
- sizeof(struct i596_tbd));
+ (int)sizeof(struct i596_tbd));
return -ENODEV;
}
#ifndef __LP64__
if (sizeof(struct i596_private) > 4096) {
printk("82596: sizeof(struct i596_private) = %d\n",
- sizeof(struct i596_private));
+ (int)sizeof(struct i596_private));
return -ENODEV;
}
#endif
for (i=0; i < 6; i++) {
eth_addr[i] = gsc_readb(LAN_PROM_ADDR + i);
}
- printk("82596.c: MAC of HP700 LAN read from EEPROM\n");
+ printk(KERN_INFO "%s: MAC of HP700 LAN read from EEPROM\n", __FILE__);
}
dev->mem_start = (unsigned long) dma_alloc_noncoherent(gen_dev,
sizeof(struct i596_private), &dma_addr, GFP_KERNEL);
if (!dev->mem_start) {
- printk("%s: Couldn't get shared memory\n", dev->name);
+ printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__);
return -ENOMEM;
}
- DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
-
for (i = 0; i < 6; i++)
- DEB(DEB_PROBE,printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]));
-
- DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));
-
- DEB(DEB_PROBE,printk(version));
+ dev->dev_addr[i] = eth_addr[i];
/* The 82596-specific entries in the device structure. */
dev->open = i596_open;
dev->priv = (void *)(dev->mem_start);
lp = dev->priv;
- DEB(DEB_INIT,printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
- dev->name, (unsigned long)lp,
- sizeof(struct i596_private), (unsigned long)&lp->scb));
memset(lp, 0, sizeof(struct i596_private));
lp->scb.command = 0;
CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private));
+ i = register_netdev(dev);
+ if (i) {
+ lp = dev->priv;
+ dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
+ (void *)dev->mem_start, lp->dma_addr);
+ return i;
+ };
+
+ DEB(DEB_PROBE, printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+ for (i = 0; i < 6; i++)
+ DEB(DEB_PROBE, printk(" %2.2X", dev->dev_addr[i]));
+ DEB(DEB_PROBE, printk(" IRQ %d.\n", dev->irq));
+ DEB(DEB_INIT, printk(KERN_INFO "%s: lp at 0x%p (%d bytes), lp->scb at 0x%p\n",
+ dev->name, lp, (int)sizeof(struct i596_private), &lp->scb));
+
return 0;
}
unsigned short status, ack_cmd = 0;
if (dev == NULL) {
- printk("i596_interrupt(): irq %d for unknown device.\n", irq);
+ printk("%s: irq %d for unknown device.\n", __FUNCTION__, irq);
return IRQ_NONE;
}
spin_lock (&lp->lock);
- wait_cmd(dev,lp,100,"i596 interrupt, timeout");
+ wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
status = lp->scb.status;
- DEB(DEB_INTS,printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
+ DEB(DEB_INTS, printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
dev->name, irq, status));
ack_cmd = status & 0xf000;
struct i596_cmd *ptr;
if ((status & 0x8000))
- DEB(DEB_INTS,printk("%s: i596 interrupt completed command.\n", dev->name));
+ DEB(DEB_INTS, printk("%s: i596 interrupt completed command.\n", dev->name));
if ((status & 0x2000))
- DEB(DEB_INTS,printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
+ DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
while (lp->cmd_head != NULL) {
CHECK_INV(lp->cmd_head, sizeof(struct i596_cmd));
ptr = lp->cmd_head;
- DEB(DEB_STATUS,printk("cmd_head->status = %04x, ->command = %04x\n",
+ DEB(DEB_STATUS, printk("cmd_head->status = %04x, ->command = %04x\n",
lp->cmd_head->status, lp->cmd_head->command));
lp->cmd_head = ptr->v_next;
lp->cmd_backlog--;
struct sk_buff *skb = tx_cmd->skb;
if ((ptr->status) & STAT_OK) {
- DEB(DEB_TXADDR,print_eth(skb->data, "tx-done"));
+ DEB(DEB_TXADDR, print_eth(skb->data, "tx-done"));
} else {
lp->stats.tx_errors++;
if ((ptr->status) & 0x0020)
unsigned short status = ((struct tdr_cmd *)ptr)->status;
if (status & 0x8000) {
- DEB(DEB_ANY,printk("%s: link ok.\n", dev->name));
+ DEB(DEB_ANY, printk("%s: link ok.\n", dev->name));
} else {
if (status & 0x4000)
printk("%s: Transceiver problem.\n", dev->name);
if (status & 0x1000)
printk("%s: Short circuit.\n", dev->name);
- DEB(DEB_TDR,printk("%s: Time %d.\n", dev->name, status & 0x07ff));
+ DEB(DEB_TDR, printk("%s: Time %d.\n", dev->name, status & 0x07ff));
}
break;
}
}
if ((status & 0x1000) || (status & 0x4000)) {
if ((status & 0x4000))
- DEB(DEB_INTS,printk("%s: i596 interrupt received a frame.\n", dev->name));
+ DEB(DEB_INTS, printk("%s: i596 interrupt received a frame.\n", dev->name));
i596_rx(dev);
/* Only RX_START if stopped - RGH 07-07-96 */
if (status & 0x1000) {
if (netif_running(dev)) {
- DEB(DEB_ERRORS,printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
+ DEB(DEB_ERRORS, printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
ack_cmd |= RX_START;
lp->stats.rx_errors++;
lp->stats.rx_fifo_errors++;
}
}
}
- wait_cmd(dev,lp,100,"i596 interrupt, timeout");
+ wait_cmd(dev, lp, 100, "i596 interrupt, timeout");
lp->scb.command = ack_cmd;
CHECK_WBACK(&lp->scb, sizeof(struct i596_scb));
CA(dev);
- wait_cmd(dev,lp,100,"i596 interrupt, exit timeout");
- DEB(DEB_INTS,printk("%s: exiting interrupt.\n", dev->name));
+ wait_cmd(dev, lp, 100, "i596 interrupt, exit timeout");
+ DEB(DEB_INTS, printk("%s: exiting interrupt.\n", dev->name));
spin_unlock (&lp->lock);
return IRQ_HANDLED;
netif_stop_queue(dev);
- DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n",
+ DEB(DEB_INIT, printk("%s: Shutting down ethercard, status was %4.4x.\n",
dev->name, lp->scb.status));
spin_lock_irqsave(&lp->lock, flags);
- wait_cmd(dev,lp,100,"close1 timed out");
+ wait_cmd(dev, lp, 100, "close1 timed out");
lp->scb.command = CUC_ABORT | RX_ABORT;
CHECK_WBACK(&lp->scb, sizeof(struct i596_scb));
CA(dev);
- wait_cmd(dev,lp,100,"close2 timed out");
+ wait_cmd(dev, lp, 100, "close2 timed out");
spin_unlock_irqrestore(&lp->lock, flags);
DEB(DEB_STRUCT,i596_display_data(dev));
i596_cleanup_cmd(dev,lp);
struct i596_private *lp = dev->priv;
int config = 0, cnt;
- DEB(DEB_MULTI,printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+ DEB(DEB_MULTI, printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
+ dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF",
+ dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
lp->cf_cmd.i596_config[8] |= 0x01;
for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
memcpy(cp, dmi->dmi_addr, 6);
if (i596_debug > 1)
- DEB(DEB_MULTI,printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
}
CHECK_WBACK_INV(&lp->mc_cmd, sizeof(struct mc_cmd));
if (num_drivers >= MAX_DRIVERS) {
/* max count of possible i82596 drivers reached */
- return -ENODEV;
+ return -ENOMEM;
}
+
+ if (num_drivers == 0)
+ printk(KERN_INFO LASI_82596_DRIVER_VERSION "\n");
if (!dev->irq) {
- printk(KERN_ERR __FILE__ ": IRQ not found for i82596 at 0x%lx\n", dev->hpa);
+ printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
+ __FILE__, dev->hpa);
return -ENODEV;
}
return -ENODEV;
}
- retval = register_netdev(netdevice);
- if (retval) {
- struct i596_private *lp = netdevice->priv;
- printk(KERN_WARNING __FILE__ ": register_netdevice ret'd %d\n", retval);
- dma_free_noncoherent(lp->dev, sizeof(struct i596_private),
- (void *)netdevice->mem_start, lp->dma_addr);
- free_netdev(netdevice);
- return -ENODEV;
- };
if (dev->id.sversion == 0x72) {
((struct i596_private *)netdevice->priv)->options = OPT_SWAP_PORT;
}
(void *)netdevice->mem_start, lp->dma_addr);
free_netdev(netdevice);
}
+ num_drivers = 0;
unregister_parisc_driver(&lan_driver);
}
}
else if (ei_local->tx2 == 0)
{
- output_page = ei_local->tx_start_page + TX_1X_PAGES;
+ output_page = ei_local->tx_start_page + TX_PAGES/2;
ei_local->tx2 = send_length;
if (ei_debug && ei_local->tx1 > 0)
printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
}
}
/* Lite-On boards have the address byte-swapped. */
- if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0)
+ if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0 || dev->dev_addr[0] == 0x02)
&& dev->dev_addr[1] == 0x00)
for (i = 0; i < 6; i+=2) {
char tmp = dev->dev_addr[i];
}
#endif /* USE_MMIO */
dev->base_addr = ioaddr;
+ rp = netdev_priv(dev);
+ rp->quirks = quirks;
rhine_power_init(dev);
dev->irq = pdev->irq;
- rp = netdev_priv(dev);
spin_lock_init(&rp->lock);
rp->pdev = pdev;
- rp->quirks = quirks;
rp->mii_if.dev = dev;
rp->mii_if.mdio_read = mdio_read;
rp->mii_if.mdio_write = mdio_write;
memcpy(header.addr3, priv->CurrentBSSID, 6);
if (priv->wep_is_on) {
- auth.alg = C80211_MGMT_AAN_SHAREDKEY;
+ auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
/* no WEP for authentication frames with TrSeqNo 1 */
if (priv->CurrentAuthentTransactionSeqNum != 1)
header.frame_ctl |= cpu_to_le16(IEEE802_11_FCTL_WEP);
} else {
- auth.alg = C80211_MGMT_AAN_OPENSYSTEM;
+ auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
}
auth.status = 0;
{
struct iw_range *range = (struct iw_range *) extra;
islpci_private *priv = netdev_priv(ndev);
- char *data;
+ u8 *data;
int i, m, rvalue;
struct obj_frequencies *freq;
union oid_res_t r;
i = 0;
while ((i < IW_MAX_BITRATES) && (*data != 0)) {
/* the result must be in bps. The card gives us 500Kbps */
- range->bitrate[i] = (__s32) (*data >> 1);
- range->bitrate[i] *= 1000000;
+ range->bitrate[i] = *data * 500000;
i++;
data++;
}
return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
}
- if ((ret =
- mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r)))
+ ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);
+ if (ret) {
+ kfree(r.ptr);
return ret;
+ }
rate = (u32) (vwrq->value / 500000);
data = r.ptr;
}
if (!data[i]) {
+ kfree(r.ptr);
return -EINVAL;
}
vwrq->value = r.u * 500000;
/* request the device for the enabled rates */
- if ((rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r)))
+ rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r);
+ if (rvalue) {
+ kfree(r.ptr);
return rvalue;
+ }
data = r.ptr;
vwrq->fixed = (data[0] != 0) && (data[1] == 0);
kfree(r.ptr);
#include "oid_mgt.h"
#define ISL3877_IMAGE_FILE "isl3877"
+#define ISL3886_IMAGE_FILE "isl3886"
#define ISL3890_IMAGE_FILE "isl3890"
static int prism54_bring_down(islpci_private *);
void *device = priv->device_base;
int powerstate = ISL38XX_PSM_POWERSAVE_STATE;
+ /* lock the interrupt handler */
+ spin_lock(&priv->slock);
+
/* received an interrupt request on a shared IRQ line
* first check whether the device is in sleep mode */
reg = readl(device + ISL38XX_CTRL_STAT_REG);
#if VERBOSE > SHOW_ERROR_MESSAGES
DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
#endif
+ spin_unlock(&priv->slock);
return IRQ_NONE;
}
- if (islpci_get_state(priv) != PRV_STATE_SLEEP)
- powerstate = ISL38XX_PSM_ACTIVE_STATE;
-
- /* lock the interrupt handler */
- spin_lock(&priv->slock);
/* check whether there is any source of interrupt on the device */
reg = readl(device + ISL38XX_INT_IDENT_REG);
reg &= ISL38XX_INT_SOURCES;
if (reg != 0) {
+ if (islpci_get_state(priv) != PRV_STATE_SLEEP)
+ powerstate = ISL38XX_PSM_ACTIVE_STATE;
+
/* reset the request bits in the Identification register */
isl38xx_w32_flush(device, reg, ISL38XX_INT_ACK_REG);
isl38xx_handle_wakeup(priv->control_block,
&powerstate, priv->device_base);
}
+ } else {
+#if VERBOSE > SHOW_ERROR_MESSAGES
+ DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
+#endif
+ spin_unlock(&priv->slock);
+ return IRQ_NONE;
}
/* sleep -> ready */
/* select the firmware file depending on the device id */
switch (pdev->device) {
- case PCIDEVICE_ISL3890:
- case PCIDEVICE_3COM6001:
- strcpy(priv->firmware, ISL3890_IMAGE_FILE);
- break;
- case PCIDEVICE_ISL3877:
+ case 0x3877:
strcpy(priv->firmware, ISL3877_IMAGE_FILE);
break;
+ case 0x3886:
+ strcpy(priv->firmware, ISL3886_IMAGE_FILE);
+ break;
+
default:
strcpy(priv->firmware, ISL3890_IMAGE_FILE);
break;
* If you have an update for this please contact prism54-devel@prism54.org
* The latest list can be found at http://prism54.org/supported_cards.php */
static const struct pci_device_id prism54_id_tbl[] = {
- /* 3COM 3CRWE154G72 Wireless LAN adapter */
- {
- PCIVENDOR_3COM, PCIDEVICE_3COM6001,
- PCIVENDOR_3COM, PCIDEVICE_3COM6001,
- 0, 0, 0
- },
-
- /* D-Link Air Plus Xtreme G A1 - DWL-g650 A1 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_DLINK, 0x3202UL,
- 0, 0, 0
- },
-
- /* I-O Data WN-G54/CB - WN-G54/CB */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_IODATA, 0xd019UL,
- 0, 0, 0
- },
-
- /* Netgear WG511 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_NETGEAR, 0x4800UL,
- 0, 0, 0
- },
-
- /* Tekram Technology clones, Allnet, Netcomm, Zyxel */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_TTL, 0x1605UL,
- 0, 0, 0
- },
-
- /* SMC2802W */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0x2802UL,
- 0, 0, 0
- },
-
- /* SMC2835W */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0x2835UL,
- 0, 0, 0
- },
-
- /* Corega CG-WLCB54GT */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_ATI, 0xc104UL,
- 0, 0, 0
- },
-
- /* I4 Z-Com XG-600 */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_I4, 0x0014UL,
- 0, 0, 0
- },
-
- /* I4 Z-Com XG-900 and clones Macer, Ovislink, Planex, Peabird, */
- /* Sitecom, Xterasys */
- {
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_I4, 0x0020UL,
- 0, 0, 0
- },
-
- /* SMC 2802W V2 */
+ /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_ACCTON, 0xee03UL,
+ 0x1260, 0x3890,
+ PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
- /* SMC 2835W V2 */
+ /* 3COM 3CRWE154G72 Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
- PCIVENDOR_SMC, 0xa835UL,
+ 0x10b7, 0x6001,
+ PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
/* Intersil PRISM Indigo Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3877,
+ 0x1260, 0x3877,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
- /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
- /* Default */
+ /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
{
- PCIVENDOR_INTERSIL, PCIDEVICE_ISL3890,
+ 0x1260, 0x3886,
PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0
},
/* .enable_wake ; we don't support this yet */
};
-static void
-prism54_get_card_model(struct net_device *ndev)
-{
- islpci_private *priv;
- char *modelp;
- int notwork = 0;
-
- priv = netdev_priv(ndev);
- switch (priv->pdev->subsystem_device) {
- case PCIDEVICE_ISL3877:
- modelp = "PRISM Indigo";
- break;
- case PCIDEVICE_ISL3886:
- modelp = "PRISM Javelin / Xbow";
- break;
- case PCIDEVICE_3COM6001:
- modelp = "3COM 3CRWE154G72";
- break;
- case 0x3202UL:
- modelp = "D-Link DWL-g650 A1";
- break;
- case 0xd019UL:
- modelp = "WN-G54/CB";
- break;
- case 0x4800UL:
- modelp = "Netgear WG511";
- break;
- case 0x2802UL:
- modelp = "SMC2802W";
- break;
- case 0xee03UL:
- modelp = "SMC2802W V2";
- notwork = 1;
- break;
- case 0x2835UL:
- modelp = "SMC2835W";
- break;
- case 0xa835UL:
- modelp = "SMC2835W V2";
- notwork = 1;
- break;
- case 0xc104UL:
- modelp = "CG-WLCB54GT";
- break;
- case 0x1605UL:
- modelp = "Tekram Technology clone";
- break;
- /* Let's leave this one out for now since it seems bogus/wrong
- * Even if the manufacturer did use 0x0000UL it may not be correct
- * by their part, therefore deserving no name ;) */
- /* case 0x0000UL:
- * modelp = "SparkLAN WL-850F";
- * break;*/
-
- /* We have two reported for the one below :( */
- case 0x0014UL:
- modelp = "I4 Z-Com XG-600 and clones";
- break;
- case 0x0020UL:
- modelp = "I4 Z-Com XG-900 and clones";
- break;
-/* Default it */
-/*
- case PCIDEVICE_ISL3890:
- modelp = "PRISM Duette/GT";
- break;
-*/
- default:
- modelp = "PRISM Duette/GT";
- }
- printk(KERN_DEBUG "%s: %s driver detected card model: %s\n",
- ndev->name, DRV_NAME, modelp);
- if ( notwork ) {
- printk(KERN_DEBUG "%s: %s Warning - This may not work\n",
- ndev->name, DRV_NAME);
- }
- return;
-}
-
/******************************************************************************
Module initialization functions
******************************************************************************/
/* firmware upload is triggered in islpci_open */
- /* Pretty card model discovery output */
- prism54_get_card_model(ndev);
-
return 0;
do_unregister_netdev:
/* General driver definitions */
-#define PCIVENDOR_INTERSIL 0x1260UL
-#define PCIVENDOR_3COM 0x10b7UL
-#define PCIVENDOR_DLINK 0x1186UL
-#define PCIVENDOR_I4 0x17cfUL
-#define PCIVENDOR_IODATA 0x10fcUL
-#define PCIVENDOR_NETGEAR 0x1385UL
-#define PCIVENDOR_SMC 0x10b8UL
-#define PCIVENDOR_ACCTON 0x1113UL
-#define PCIVENDOR_ATI 0x1259UL
-#define PCIVENDOR_TTL 0x16a5UL
-
-#define PCIDEVICE_ISL3877 0x3877UL
-#define PCIDEVICE_ISL3886 0x3886UL
-#define PCIDEVICE_ISL3890 0x3890UL
-#define PCIDEVICE_3COM6001 0x6001UL
#define PCIDEVICE_LATENCY_TIMER_MIN 0x40
#define PCIDEVICE_LATENCY_TIMER_VAL 0x50
OID_UNKNOWN(OID_INL_MEMORY, 0xFF020002),
OID_U32_C(OID_INL_MODE, 0xFF020003),
OID_UNKNOWN(OID_INL_COMPONENT_NR, 0xFF020004),
- OID_UNKNOWN(OID_INL_VERSION, 0xFF020005),
+ OID_STRUCT(OID_INL_VERSION, 0xFF020005, u8[8], OID_TYPE_RAW),
OID_UNKNOWN(OID_INL_INTERFACE_ID, 0xFF020006),
OID_UNKNOWN(OID_INL_COMPONENT_ID, 0xFF020007),
OID_U32_C(OID_INL_CONFIG, 0xFF020008),
BUG_ON(OID_NUM_LAST <= n);
BUG_ON(extra > isl_oid[n].range);
+ res->ptr = NULL;
+
if (!priv->mib)
/* memory has been freed */
return -1;
struct dino_device *dino_dev; // Dino specific control struct
const char *version = "unknown";
const int name_len = 32;
+ char hw_path[64];
char *name;
int is_cujo = 0;
struct pci_bus *bus;
-
+
name = kmalloc(name_len, GFP_KERNEL);
- if(name)
- snprintf(name, name_len, "Dino %s", dev->dev.bus_id);
+ if(name) {
+ print_pa_hwpath(dev, hw_path);
+ snprintf(name, name_len, "Dino [%s]", hw_path);
+ }
else
name = "Dino";
sg_dma_len(startsg) = 0;
dma_offset = (unsigned long) pide & ~IOVP_MASK;
n_mappings++;
+#if defined(ZX1_SUPPORT)
+ /* Pluto IOMMU IO Virt Address is not zero based */
+ sg_dma_address(dma_sg) = pide | ioc->ibase;
+#else
+ /* SBA, ccio, and dino are zero based.
+ * Trying to save a few CPU cycles for most users.
+ */
sg_dma_address(dma_sg) = pide;
+#endif
pdirp = &(ioc->pdir_base[pide >> IOVP_SHIFT]);
prefetchw(pdirp);
}
#include <asm/byteorder.h> /* get in-line asm for swab */
#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <asm/io.h> /* gsc_read/write functions */
+#include <asm/io.h> /* read/write functions */
#ifdef CONFIG_SUPERIO
#include <asm/superio.h>
#endif
#endif
-#define READ_U8(addr) gsc_readb(addr)
-#define READ_U16(addr) le16_to_cpu(gsc_readw((u16 *) (addr)))
-#define READ_U32(addr) le32_to_cpu(gsc_readl((u32 *) (addr)))
-#define READ_REG16(addr) gsc_readw((u16 *) (addr))
-#define READ_REG32(addr) gsc_readl((u32 *) (addr))
-#define WRITE_U8(value, addr) gsc_writeb(value, addr)
-#define WRITE_U16(value, addr) gsc_writew(cpu_to_le16(value), (u16 *) (addr))
-#define WRITE_U32(value, addr) gsc_writel(cpu_to_le32(value), (u32 *) (addr))
-#define WRITE_REG16(value, addr) gsc_writew(value, (u16 *) (addr))
-#define WRITE_REG32(value, addr) gsc_writel(value, (u32 *) (addr))
-
-
-#define IOSAPIC_REG_SELECT 0
+#define IOSAPIC_REG_SELECT 0x00
#define IOSAPIC_REG_WINDOW 0x10
#define IOSAPIC_REG_EOI 0x40
#define IOSAPIC_IRDT_ENTRY(idx) (0x10+(idx)*2)
#define IOSAPIC_IRDT_ENTRY_HI(idx) (0x11+(idx)*2)
+static inline unsigned int iosapic_read(unsigned long iosapic, unsigned int reg)
+{
+ writel(reg, iosapic + IOSAPIC_REG_SELECT);
+ return readl(iosapic + IOSAPIC_REG_WINDOW);
+}
+
+static inline void iosapic_write(unsigned long iosapic, unsigned int reg, u32 val)
+{
+ writel(reg, iosapic + IOSAPIC_REG_SELECT);
+ writel(val, iosapic + IOSAPIC_REG_WINDOW);
+}
+
/*
-** FIXME: revisit which GFP flags we should really be using.
** GFP_KERNEL includes __GFP_WAIT flag and that may not
** be acceptable. Since this is boot time, we shouldn't have
** to wait ever and this code should (will?) never get called
#define IOSAPIC_UNLOCK(lck) spin_unlock_irqrestore(lck, irqflags)
-#define IOSAPIC_VERSION_MASK 0x000000ff
-#define IOSAPIC_VERSION_SHIFT 0x0
-#define IOSAPIC_VERSION(ver) \
- (int) ((ver & IOSAPIC_VERSION_MASK) >> IOSAPIC_VERSION_SHIFT)
+#define IOSAPIC_VERSION_MASK 0x000000ff
+#define IOSAPIC_VERSION(ver) ((int) (ver & IOSAPIC_VERSION_MASK))
#define IOSAPIC_MAX_ENTRY_MASK 0x00ff0000
-
#define IOSAPIC_MAX_ENTRY_SHIFT 0x10
-#define IOSAPIC_IRDT_MAX_ENTRY(ver) \
- (int) ((ver&IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
+#define IOSAPIC_IRDT_MAX_ENTRY(ver) \
+ (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
/* bits in the "low" I/O Sapic IRdT entry */
#define IOSAPIC_IRDT_ENABLE 0x10000
#define IOSAPIC_IRDT_ID_EID_SHIFT 0x10
-
-#define IOSAPIC_EOI(eoi_addr, eoi_data) gsc_writel(eoi_data, eoi_addr)
-
static struct iosapic_info *iosapic_list;
static spinlock_t iosapic_lock;
static int iosapic_count;
struct irt_entry *p = table;
int i;
- printk(KERN_DEBUG MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
- printk(KERN_DEBUG MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
+ printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
+ printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
table,
num_entries,
(int) sizeof(struct irt_entry));
for (i = 0 ; i < num_entries ; i++, p++) {
- printk(KERN_DEBUG MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
+ printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
p->entry_type, p->entry_length, p->interrupt_type,
p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
p->src_seg_id, p->dest_iosapic_intin,
static irqreturn_t
iosapic_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
- struct vector_info *vi = (struct vector_info *)dev_id;
+ struct vector_info *vi = (struct vector_info *) dev_id;
extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
int irq_num = vi->iosapic->isi_region->data.irqbase + vi->irqline;
- DBG("iosapic_interrupt(): irq %d line %d eoi %p\n",
- irq, vi->irqline, vi->eoi_addr);
+ DBG("iosapic_interrupt(): irq %d line %d eoi 0x%p 0x%x\n",
+ irq, vi->irqline, vi->eoi_addr, vi->eoi_data);
+
+ /* Do NOT need to mask/unmask IRQ. processor is already masked. */
-/* FIXME: Need to mask/unmask? processor IRQ is already masked... */
do_irq(&vi->iosapic->isi_region->action[vi->irqline], irq_num, regs);
/*
+ ** PARISC only supports PCI devices below I/O SAPIC.
** PCI only supports level triggered in order to share IRQ lines.
- ** I/O SAPIC must always issue EOI.
+ ** ergo I/O SAPIC must always issue EOI on parisc.
+ **
+ ** i386/ia64 support ISA devices and have to deal with
+ ** edge-triggered interrupts too.
*/
- IOSAPIC_EOI(vi->eoi_addr, vi->eoi_data);
-
+ __raw_writel(vi->eoi_data, vi->eoi_addr);
return IRQ_HANDLED;
}
ASSERT(tmp == 0);
vi->eoi_addr = (u32 *) (isi->isi_hpa + IOSAPIC_REG_EOI);
- vi->eoi_data = cpu_to_le32(vi->irqline);
-
+ vi->eoi_data = cpu_to_le32(vi->txn_data);
ASSERT(NULL != isi->isi_region);
DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
struct iosapic_info *isp = vi->iosapic;
u8 idx = vi->irqline;
- /* point the window register to the lower word */
- WRITE_U32(IOSAPIC_IRDT_ENTRY(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
- *dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
-
- /* point the window register to the higher word */
- WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(idx), isp->isi_hpa+IOSAPIC_REG_SELECT);
- *dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ *dp0 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(idx));
+ *dp1 = iosapic_read(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(idx));
}
ASSERT(NULL != isp);
ASSERT(0 != isp->isi_hpa);
- DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p WINDOW %p 0x%x 0x%x\n",
+ DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %p 0x%x 0x%x\n",
vi->irqline,
- isp->isi_hpa, isp->isi_hpa+IOSAPIC_REG_WINDOW,
+ isp->isi_hpa,
dp0, dp1);
- /* point the window register to the lower word */
- WRITE_U32(IOSAPIC_IRDT_ENTRY(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
- WRITE_U32( dp0, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
/* Read the window register to flush the writes down to HW */
- dp0 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ dp0 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
- /* point the window register to the higher word */
- WRITE_U32(IOSAPIC_IRDT_ENTRY_HI(vi->irqline), isp->isi_hpa+IOSAPIC_REG_SELECT);
- WRITE_U32( dp1, isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ iosapic_write(isp->isi_hpa, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
/* Read the window register to flush the writes down to HW */
- dp1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ dp1 = readl(isp->isi_hpa+IOSAPIC_REG_WINDOW);
}
iosapic_set_irt_data(vi, &d0, &d1);
iosapic_wr_irt_entry(vi, d0, d1);
-
#ifdef DEBUG_IOSAPIC_IRT
{
u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
- while (t < vi->eoi_addr) printk(" %x", READ_U32(t++));
+ for ( ; t < vi->eoi_addr; t++)
+ printk(" %x", readl(t));
printk("\n");
}
struct iosapic_info *isp = vi->iosapic;
for (d0=0x10; d0<0x1e; d0++) {
- /* point the window register to the lower word */
- WRITE_U32(d0, isp->isi_hpa+IOSAPIC_REG_SELECT);
-
- /* read the word */
- d1 = READ_U32(isp->isi_hpa+IOSAPIC_REG_WINDOW);
+ d1 = iosapic_read(isp->isi_hpa, d0);
printk(" %x", d1);
}
}
#endif
/*
- ** KLUGE: IRQ should not be asserted when Drivers enabling their IRQ.
- ** PCI supports level triggered in order to share IRQ lines.
- **
- ** Issueing I/O SAPIC an EOI causes an interrupt iff IRQ line is
- ** asserted.
+ ** Issueing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
+ ** asserted. IRQ generally should not be asserted when a driver
+ ** enables their IRQ. It can lead to "interesting" race conditions
+ ** in the driver initialization sequence.
*/
- IOSAPIC_EOI(vi->eoi_addr, vi->eoi_data);
+ __raw_writel(vi->eoi_data, vi->eoi_addr);
}
ASSERT(isi);
ASSERT(isi->isi_hpa);
- /* point window to the version register */
- WRITE_U32(IOSAPIC_REG_VERSION, isi->isi_hpa+IOSAPIC_REG_SELECT);
-
- /* now read the version register */
- return (READ_U32(isi->isi_hpa+IOSAPIC_REG_WINDOW));
+ return iosapic_read(isi->isi_hpa, IOSAPIC_REG_VERSION);
}
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/init.h> /* for __init and __devinit */
-/* #define PCI_DEBUG enable ASSERT */
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/irq.h> /* for struct irq_region support */
#include <asm/pdc.h>
+#include <asm/pdcpat.h>
#include <asm/page.h>
#include <asm/segment.h>
#include <asm/system.h>
#define DBG_PAT(x...)
#endif
+#ifdef DEBUG_LBA
+#undef ASSERT
+#define ASSERT(expr) \
+ if(!(expr)) { \
+ printk("\n%s:%d: Assertion " #expr " failed!\n", \
+ __FILE__, __LINE__); \
+ panic(#expr); \
+ }
+#else
+#define ASSERT(expr)
+#endif
+
+
/*
** Config accessor functions only pass in the 8-bit bus number and not
** the 8-bit "PCI Segment" number. Each LBA will be assigned a PCI bus
#define LBA_HINT_CFG 0x0310
#define LBA_HINT_BASE 0x0380 /* 14 registers at every 8 bytes. */
+#define LBA_BUS_MODE 0x0620
+
/* ERROR regs are needed for config cycle kluges */
#define LBA_ERROR_CONFIG 0x0680
#define LBA_SMART_MODE 0x20
#define LBA_IOSAPIC_BASE 0x800 /* Offset of IRQ logic */
/* non-postable I/O port space, densely packed */
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
#define LBA_ASTRO_PORT_BASE (0xfffffffffee00000UL)
#else
#define LBA_ASTRO_PORT_BASE (0xfee00000UL)
#endif
+#define ELROY_HVERS 0x782
+#define MERCURY_HVERS 0x783
+#define QUICKSILVER_HVERS 0x784
+
+static inline int IS_ELROY(struct parisc_device *d)
+{
+ return (d->id.hversion == ELROY_HVERS);
+}
+
+static inline int IS_MERCURY(struct parisc_device *d)
+{
+ return (d->id.hversion == MERCURY_HVERS);
+}
+
+static inline int IS_QUICKSILVER(struct parisc_device *d)
+{
+ return (d->id.hversion == QUICKSILVER_HVERS);
+}
+
/*
** lba_device: Per instance Elroy data structure
spinlock_t lba_lock;
void *iosapic_obj;
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
unsigned long iop_base; /* PA_VIEW - for IO port accessor funcs */
#endif
{
u8 first_bus = d->hba.hba_bus->secondary;
u8 last_sub_bus = d->hba.hba_bus->subordinate;
-#if 0
-/* FIXME - see below in this function */
- u8 dev = PCI_SLOT(dfn);
- u8 func = PCI_FUNC(dfn);
-#endif
ASSERT(bus >= first_bus);
ASSERT(bus <= last_sub_bus);
return(FALSE);
}
-#if 0
-/*
-** FIXME: Need to implement code to fill the devices bitmap based
-** on contents of the local pci_bus tree "data base".
-** pci_register_ops() walks the bus for us and builds the tree.
-** For now, always do the config cycle.
-*/
- bus -= first_bus;
-
- return (((d->devices[bus][dev]) >> func) & 0x1);
-#else
return TRUE;
-#endif
}
return(data);
}
+#ifdef CONFIG_PARISC64
+#define pat_cfg_addr(bus, devfn, addr) (((bus) << 16) | ((devfn) << 8) | (addr))
+
+static int pat_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
+{
+ int tok = pat_cfg_addr(bus->number, devfn, pos);
+ u32 tmp;
+ int ret = pdc_pat_io_pci_cfg_read(tok, size, &tmp);
+
+ DBG_CFG("%s(%d:%d.%d+0x%02x) -> 0x%x %d\n", __FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), pos, tmp, ret);
+
+ switch (size) {
+ case 1: *data = (u8) tmp; return (tmp == (u8) ~0);
+ case 2: *data = (u16) tmp; return (tmp == (u16) ~0);
+ case 4: *data = (u32) tmp; return (tmp == (u32) ~0);
+ }
+ *data = ~0;
+ return (ret);
+}
+
+static int pat_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
+{
+ int tok = pat_cfg_addr(bus->number, devfn, pos);
+ int ret = pdc_pat_io_pci_cfg_write(tok, size, data);
+
+ DBG_CFG("%s(%d:%d.%d+0x%02x, 0x%lx/%d)\n", __FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), pos, data, size);
+ return (ret);
+}
+
+static struct pci_ops pat_cfg_ops = {
+ .read = pat_cfg_read,
+ .write = pat_cfg_write,
+};
+#else
+/* keep the compiler from complaining about undeclared variables */
+#define pat_cfg_ops lba_cfg_ops
+#endif
static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
{
}
DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+
/* Basic Algorithm */
LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
switch(size) {
}
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
/*
** Determine if a device is already configured.
}
}
}
+#else
+#define lba_claim_dev_resources(dev)
#endif
lba_dump_res(&iomem_resource, 2);
}
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
if (ldev->hba.gmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.gmmio_space));
if (err < 0) {
bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
#endif
-#ifdef __LP64__
if (is_pdc_pat()) {
/* Claim resources for PDC's devices */
lba_claim_dev_resources(dev);
}
-#endif
/*
** P2PB's have no IRQs. ignore them.
};
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
#define PIOP_TO_GMMIO(lba, addr) \
((lba)->iop_base + (((addr)&0xFFFC)<<10) + ((addr)&3))
}
}
}
-#endif /* __LP64__ */
+#else
+/* keep compiler from complaining about missing declarations */
+#define lba_pat_port_ops lba_astro_port_ops
+#define lba_pat_resources(pa_dev, lba_dev)
+#endif /* CONFIG_PARISC64 */
static void
unsigned long rsize;
int lba_num;
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
/*
** Sign extend all BAR values on "legacy" platforms.
** "Sprockets" PDC (Forte/Allegro) initializes everything
printk("\n");
#endif /* DEBUG_LBA_PAT */
-#ifdef __LP64__
+#ifdef CONFIG_PARISC64
/*
* FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
* Only N-Class and up can really make use of Get slot status.
** have work to do.
*/
static int __init
-lba_driver_callback(struct parisc_device *dev)
+lba_driver_probe(struct parisc_device *dev)
{
struct lba_device *lba_dev;
struct pci_bus *lba_bus;
/* Read HW Rev First */
func_class = READ_REG32(dev->hpa + LBA_FCLASS);
- func_class &= 0xf;
-
- switch (func_class) {
- case 0: version = "TR1.0"; break;
- case 1: version = "TR2.0"; break;
- case 2: version = "TR2.1"; break;
- case 3: version = "TR2.2"; break;
- case 4: version = "TR3.0"; break;
- case 5: version = "TR4.0"; break;
- default: version = "TR4+";
- }
- printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
- MODULE_NAME, version, func_class & 0xf, dev->hpa);
+ if (IS_ELROY(dev)) {
+ func_class &= 0xf;
+ switch (func_class) {
+ case 0: version = "TR1.0"; break;
+ case 1: version = "TR2.0"; break;
+ case 2: version = "TR2.1"; break;
+ case 3: version = "TR2.2"; break;
+ case 4: version = "TR3.0"; break;
+ case 5: version = "TR4.0"; break;
+ default: version = "TR4+";
+ }
+ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+ MODULE_NAME, version, func_class & 0xf, dev->hpa);
+
+ /* Just in case we find some prototypes... */
+ } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
+ func_class &= 0xff;
+ version = kmalloc(6, GFP_KERNEL);
+ sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf));
+ /* We could use one printk for both and have it outside,
+ * but for the mask for func_class.
+ */
+ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+ MODULE_NAME, version, func_class & 0xff, dev->hpa);
+ }
- /* Just in case we find some prototypes... */
if (func_class < 2) {
- printk(KERN_WARNING "Can't support LBA older than TR2.1 "
- "- continuing under adversity.\n");
+ printk(KERN_WARNING "Can't support LBA older than TR2.1"
+ " - continuing under adversity.\n");
}
/*
/* ---------- Third : setup I/O Port and MMIO resources --------- */
-#ifdef __LP64__
if (is_pdc_pat()) {
/* PDC PAT firmware uses PIOP region of GMMIO space. */
pci_port = &lba_pat_port_ops;
-
/* Go ask PDC PAT what resources this LBA has */
lba_pat_resources(dev, lba_dev);
- } else
-#endif
- {
+ } else {
/* Sprockets PDC uses NPIOP region */
pci_port = &lba_astro_port_ops;
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
- &lba_cfg_ops, NULL);
+ is_pdc_pat() ? &pat_cfg_ops : &lba_cfg_ops,
+ NULL);
-#ifdef __LP64__
if (is_pdc_pat()) {
/* assign resources to un-initialized devices */
DBG_PAT("LBA pci_bus_assign_resources()\n");
lba_dump_res(&lba_dev->hba.lmmio_space, 2);
#endif
}
-#endif
/*
** Once PCI register ops has walked the bus, access to config
}
static struct parisc_device_id lba_tbl[] = {
- { HPHW_BRIDGE, HVERSION_REV_ANY_ID, 0x782, 0xa },
+ { HPHW_BRIDGE, HVERSION_REV_ANY_ID, ELROY_HVERS, 0xa },
+ { HPHW_BRIDGE, HVERSION_REV_ANY_ID, MERCURY_HVERS, 0xa },
+ { HPHW_BRIDGE, HVERSION_REV_ANY_ID, QUICKSILVER_HVERS, 0xa },
{ 0, }
};
static struct parisc_driver lba_driver = {
.name = MODULE_NAME,
.id_table = lba_tbl,
- .probe = lba_driver_callback,
+ .probe = lba_driver_probe,
};
/*
static int led_proc_write(struct file *file, const char *buf,
unsigned long count, void *data)
{
- char *cur, lbuf[count];
+ char *cur, lbuf[count + 1];
int d;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- memset(lbuf, 0, count);
+ memset(lbuf, 0, count + 1);
if (copy_from_user(lbuf, buf, count))
return -EFAULT;
break;
case LED_HASLCD:
- while (*cur && cur[strlen(cur)-1] == '\n')
+ if (*cur && cur[strlen(cur)-1] == '\n')
cur[strlen(cur)-1] = 0;
if (*cur == 0)
cur = lcd_text_default;
#include <linux/mm.h>
#include <linux/string.h>
-#undef PCI_DEBUG /* for ASSERT */
#include <linux/pci.h>
-#undef PCI_DEBUG
#include <asm/byteorder.h>
#include <asm/io.h>
#include <linux/proc_fs.h>
#include <asm/runway.h> /* for proc_runway_root */
#include <asm/pdc.h> /* for PDC_MODEL_* */
+#include <asm/pdcpat.h> /* for is_pdc_pat() */
#include <asm/parisc-device.h>
+
+/* declared in arch/parisc/kernel/setup.c */
+extern struct proc_dir_entry * proc_mckinley_root;
+
#define MODULE_NAME "SBA"
#ifdef CONFIG_PROC_FS
** Don't even think about messing with it unless you have
** plenty of 710's to sacrifice to the computer gods. :^)
*/
+#undef DEBUG_SBA_ASSERT
#undef DEBUG_SBA_INIT
#undef DEBUG_SBA_RUN
#undef DEBUG_SBA_RUN_SG
#undef DEBUG_LARGE_SG_ENTRIES
#undef DEBUG_DMB_TRAP
-#define SBA_INLINE __inline__
-
#ifdef DEBUG_SBA_INIT
#define DBG_INIT(x...) printk(x)
#else
#define DBG_RES(x...)
#endif
+#ifdef DEBUG_SBA_ASSERT
+#undef ASSERT
+#define ASSERT(expr) \
+ if(!(expr)) { \
+ printk("\n%s:%d: Assertion " #expr " failed!\n", \
+ __FILE__, __LINE__); \
+ panic(#expr); \
+ }
+#else
+#define ASSERT(expr)
+#endif
+
+
+#if defined(__LP64__) && !defined(CONFIG_PDC_NARROW)
+/* "low end" PA8800 machines use ZX1 chipset */
+#define ZX1_SUPPORT
+#endif
+
+#define SBA_INLINE __inline__
+
+
/*
** The number of pdir entries to "free" before issueing
** a read to PCOM register to flush out PCOM writes.
#define REOG_MERCED_PORT 0x805
#define REOG_ROPES_PORT 0x783
+#define PLUTO_MCKINLEY_PORT 0x880
+#define PLUTO_ROPES_PORT 0x784
+
#define SBA_FUNC_ID 0x0000 /* function id */
#define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
#define IS_IKE(id) \
(((id)->hversion == IKE_MERCED_PORT) || ((id)->hversion == IKE_ROPES_PORT))
+#define IS_PLUTO(id) \
+(((id)->hversion == PLUTO_MCKINLEY_PORT) || ((id)->hversion == PLUTO_ROPES_PORT))
+
#define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
#define ASTRO_IOC_OFFSET 0x20000
/* Ike's IOC's occupy functions 2 and 3 (not 0 and 1) */
#define IKE_IOC_OFFSET(p) ((p+2)*SBA_FUNC_SIZE)
+#define PLUTO_IOC_OFFSET 0x1000
+
#define IOC_CTRL 0x8 /* IOC_CTRL offset */
#define IOC_CTRL_TC (1 << 0) /* TOC Enable */
#define IOC_CTRL_CE (1 << 1) /* Coalesce Enable */
#define IOC_CTRL_RM (1 << 8) /* Real Mode */
#define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */
-#define MAX_IOC 2 /* per Ike. Astro only has 1 */
+#define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */
/*
#define IOC_TCNFG 0x318
#define IOC_PDIR_BASE 0x320
-#define IOC_IOVA_SPACE_BASE 0 /* IOVA ranges start at 0 */
+/* AGP GART driver looks for this */
+#define SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
+
/*
** IOC supports 4/8/16/64KB page sizes (see TCNFG register)
** page since the Virtual Coherence Index has to be generated
** and updated for each page.
**
-** IOVP_SIZE could only be greater than PAGE_SIZE if we are
-** confident the drivers really only touch the next physical
-** page iff that driver instance owns it.
+** PAGE_SIZE could be greater than IOVP_SIZE. But not the inverse.
*/
#define IOVP_SIZE PAGE_SIZE
#define IOVP_SHIFT PAGE_SHIFT
unsigned long ioc_hpa; /* I/O MMU base address */
char *res_map; /* resource map, bit == pdir entry */
u64 *pdir_base; /* physical base address */
-
+ unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
+ unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
+#ifdef ZX1_SUPPORT
+ unsigned long iovp_mask; /* help convert IOVA to IOVP */
+#endif
unsigned long *res_hint; /* next avail IOVP - circular search */
spinlock_t res_lock;
- unsigned long hint_mask_pdir; /* bits used for DMA hints */
unsigned int res_bitshift; /* from the LEFT! */
unsigned int res_size; /* size of resource map in bytes */
+#if SBA_HINT_SUPPORT
+/* FIXME : DMA HINTs not used */
+ unsigned long hint_mask_pdir; /* bits used for DMA hints */
unsigned int hint_shift_pdir;
+#endif
#if DELAYED_RESOURCE_CNT > 0
int saved_cnt;
struct sba_dma_pair {
/* STUFF We don't need in performance path */
unsigned int pdir_size; /* in bytes, determined by IOV Space size */
- unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
- unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
};
struct sba_device {
/* Looks nice and keeps the compiler happy */
#define SBA_DEV(d) ((struct sba_device *) (d))
+#if SBA_AGP_SUPPORT
+static int reserve_sba_gart = 1;
+#endif
#define ROUNDUP(x,y) ((x + ((y)-1)) & ~((y)-1))
sba_dump_tlb(unsigned long hpa)
{
DBG_INIT("IO TLB at 0x%lx\n", hpa);
- DBG_INIT("IOC_IBASE : %Lx\n", READ_REG64(hpa+IOC_IBASE));
- DBG_INIT("IOC_IMASK : %Lx\n", READ_REG64(hpa+IOC_IMASK));
- DBG_INIT("IOC_TCNFG : %Lx\n", READ_REG64(hpa+IOC_TCNFG));
- DBG_INIT("IOC_PDIR_BASE: %Lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
+ DBG_INIT("IOC_IBASE : 0x%Lx\n", READ_REG64(hpa+IOC_IBASE));
+ DBG_INIT("IOC_IMASK : 0x%Lx\n", READ_REG64(hpa+IOC_IMASK));
+ DBG_INIT("IOC_TCNFG : 0x%Lx\n", READ_REG64(hpa+IOC_TCNFG));
+ DBG_INIT("IOC_PDIR_BASE: 0x%Lx\n", READ_REG64(hpa+IOC_PDIR_BASE));
DBG_INIT("\n");
}
+#else
+#define sba_dump_ranges(x)
+#define sba_dump_tlb(x)
#endif
#define PAGES_PER_RANGE 1 /* could increase this to 4 or 8 if needed */
/* Convert from IOVP to IOVA and vice versa. */
-#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((iovp) | (offset) | ((hint_reg)<<(ioc->hint_shift_pdir)))
-#define SBA_IOVP(ioc,iova) ((iova) & ioc->hint_mask_pdir)
-/* FIXME : review these macros to verify correctness and usage */
+#ifdef ZX1_SUPPORT
+/* Pluto (aka ZX1) boxes need to set or clear the ibase bits appropriately */
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((ioc->ibase) | (iovp) | (offset))
+#define SBA_IOVP(ioc,iova) ((iova) & (ioc)->iovp_mask)
+#else
+/* only support Astro and ancestors. Saves a few cycles in key places */
+#define SBA_IOVA(ioc,iovp,offset,hint_reg) ((iovp) | (offset))
+#define SBA_IOVP(ioc,iova) (iova)
+#endif
+
#define PDIR_INDEX(iovp) ((iovp)>>IOVP_SHIFT)
-#define MKIOVP(dma_hint,pide) (dma_addr_t)((long)(dma_hint) | ((long)(pide) << IOVP_SHIFT))
-#define MKIOVA(iovp,offset) (dma_addr_t)((long)iovp | (long)offset)
#define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n)))
#define RESMAP_IDX_MASK (sizeof(unsigned long) - 1)
*
***************************************************************/
+#if SBA_HINT_SUPPORT
#define SBA_DMA_HINT(ioc, val) ((val) << (ioc)->hint_shift_pdir)
-
+#endif
typedef unsigned long space_t;
#define KERNEL_SPACE 0
*
* Given a virtual address (vba, arg2) and space id, (sid, arg1)
* sba_io_pdir_entry() loads the I/O PDIR entry pointed to by
- * pdir_ptr (arg0). Each IO Pdir entry consists of 8 bytes as
- * shown below (MSB == bit 0):
+ * pdir_ptr (arg0).
+ * Using the bass-ackwards HP bit numbering, Each IO Pdir entry
+ * for Astro/Ike looks like:
+ *
*
* 0 19 51 55 63
* +-+---------------------+----------------------------------+----+--------+
* |V| U | PPN[43:12] | U | VI |
* +-+---------------------+----------------------------------+----+--------+
*
- * V == Valid Bit
+ * Pluto is basically identical, supports fewer physical address bits:
+ *
+ * 0 23 51 55 63
+ * +-+------------------------+-------------------------------+----+--------+
+ * |V| U | PPN[39:12] | U | VI |
+ * +-+------------------------+-------------------------------+----+--------+
+ *
+ * V == Valid Bit (Most Significant Bit is bit 0)
* U == Unused
* PPN == Physical Page Number
* VI == Virtual Index (aka Coherent Index)
*
- * The physical address fields are filled with the results of the LPA
- * instruction. The virtual index field is filled with the results of
- * of the LCI (Load Coherence Index) instruction. The 8 bits used for
- * the virtual index are bits 12:19 of the value returned by LCI.
+ * LPA instruction output is put into PPN field.
+ * LCI (Load Coherence Index) instruction provides the "VI" bits.
*
- * We need to pre-swap the bytes since PCX-W is Big Endian.
+ * We pre-swap the bytes since PCX-W is Big Endian and the
+ * IOMMU uses little endian for the pdir.
*/
ASSERT(sid == KERNEL_SPACE);
pa = virt_to_phys(vba);
- pa &= ~4095ULL; /* clear out offset bits */
+ pa &= IOVP_MASK;
mtsp(sid,1);
asm("lci 0(%%sr1, %1), %0" : "=r" (ci) : "r" (vba));
} while (byte_cnt > 0);
}
- WRITE_REG(iovp, ioc->ioc_hpa+IOC_PCOM);
+ WRITE_REG( SBA_IOVA(ioc, iovp, 0, 0), ioc->ioc_hpa+IOC_PCOM);
}
/**
pide = sba_alloc_range(ioc, size);
iovp = (dma_addr_t) pide << IOVP_SHIFT;
- DBG_RUN("%s() 0x%p -> 0x%lx",
+ DBG_RUN("%s() 0x%p -> 0x%lx\n",
__FUNCTION__, addr, (long) iovp | offset);
pdir_start = &(ioc->pdir_base[pide]);
ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr, 0);
- DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n",
+ DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n",
pdir_start,
(u8) (((u8 *) pdir_start)[7]),
(u8) (((u8 *) pdir_start)[6]),
ioc->usingle_pages += size >> IOVP_SHIFT;
#endif
+ sba_mark_invalid(ioc, iova, size);
+
#if DELAYED_RESOURCE_CNT > 0
+ /* Delaying when we re-use a IO Pdir entry reduces the number
+ * of MMIO reads needed to flush writes to the PCOM register.
+ */
d = &(ioc->saved[ioc->saved_cnt]);
d->iova = iova;
d->size = size;
if (++(ioc->saved_cnt) >= DELAYED_RESOURCE_CNT) {
int cnt = ioc->saved_cnt;
while (cnt--) {
- sba_mark_invalid(ioc, d->iova, d->size);
sba_free_range(ioc, d->iova, d->size);
d--;
}
READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
}
#else /* DELAYED_RESOURCE_CNT == 0 */
- sba_mark_invalid(ioc, iova, size);
sba_free_range(ioc, iova, size);
READ_REG(ioc->ioc_hpa+IOC_PCOM); /* flush purges */
#endif /* DELAYED_RESOURCE_CNT == 0 */
return (void *) pdir_base;
}
+static void
+sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+{
+ /* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
+ extern void lba_set_iregs(struct parisc_device *, u32, u32);
+
+ u32 iova_space_mask;
+ u32 iova_space_size;
+ int iov_order, tcnfg;
+ struct parisc_device *lba;
+#if SBA_AGP_SUPPORT
+ int agp_found = 0;
+#endif
+ /*
+ ** Firmware programs the base and size of a "safe IOVA space"
+ ** (one that doesn't overlap memory or LMMIO space) in the
+ ** IBASE and IMASK registers.
+ */
+ ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE);
+ iova_space_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1;
+
+ if ((ioc->ibase < 0xfed00000UL) && ((ioc->ibase + iova_space_size) > 0xfee00000UL)) {
+ printk("WARNING: IOV space overlaps local config and interrupt message, truncating\n");
+ iova_space_size /= 2;
+ }
+
+ /*
+ ** iov_order is always based on a 1GB IOVA space since we want to
+ ** turn on the other half for AGP GART.
+ */
+ iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT));
+ ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
+
+ DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n",
+ __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20,
+ iov_order + PAGE_SHIFT);
+
+ ioc->pdir_base = (void *) __get_free_pages(GFP_KERNEL,
+ get_order(ioc->pdir_size));
+ if (!ioc->pdir_base)
+ panic("Couldn't allocate I/O Page Table\n");
+
+ memset(ioc->pdir_base, 0, ioc->pdir_size);
+
+ DBG_INIT("%s() pdir %p size %x\n",
+ __FUNCTION__, ioc->pdir_base, ioc->pdir_size);
+
+#if SBA_HINT_SUPPORT
+ ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
+ ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
+
+ DBG_INIT(" hint_shift_pdir %x hint_mask_pdir %lx\n",
+ ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+#endif
+
+ ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+ WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+ /* build IMASK for IOC and Elroy */
+ iova_space_mask = 0xffffffff;
+ iova_space_mask <<= (iov_order + PAGE_SHIFT);
+ ioc->imask = iova_space_mask;
+#ifdef ZX1_SUPPORT
+ ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1);
+#endif
+ sba_dump_tlb(ioc->ioc_hpa);
+
+ /*
+ ** setup Mercury IBASE/IMASK registers as well.
+ */
+ for (lba = sba->child; lba; lba = lba->sibling) {
+ int rope_num = (lba->hpa >> 13) & 0xf;
+ if (rope_num >> 3 == ioc_num)
+ lba_set_iregs(lba, ioc->ibase, ioc->imask);
+ }
+
+ WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
+
+#ifdef __LP64__
+ /*
+ ** Setting the upper bits makes checking for bypass addresses
+ ** a little faster later on.
+ */
+ ioc->imask |= 0xFFFFFFFF00000000UL;
+#endif
+
+ /* Set I/O PDIR Page size to system page size */
+ switch (PAGE_SHIFT) {
+ case 12: tcnfg = 0; break; /* 4K */
+ case 13: tcnfg = 1; break; /* 8K */
+ case 14: tcnfg = 2; break; /* 16K */
+ case 16: tcnfg = 3; break; /* 64K */
+ default:
+ panic(__FILE__ "Unsupported system page size %d",
+ 1 << PAGE_SHIFT);
+ break;
+ }
+ WRITE_REG(tcnfg, ioc->ioc_hpa + IOC_TCNFG);
+
+ /*
+ ** Program the IOC's ibase and enable IOVA translation
+ ** Bit zero == enable bit.
+ */
+ WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa + IOC_IBASE);
+
+ /*
+ ** Clear I/O TLB of any possible entries.
+ ** (Yes. This is a bit paranoid...but so what)
+ */
+ WRITE_REG(ioc->ibase | 31, ioc->ioc_hpa + IOC_PCOM);
+
+#if SBA_AGP_SUPPORT
+ /*
+ ** If an AGP device is present, only use half of the IOV space
+ ** for PCI DMA. Unfortunately we can't know ahead of time
+ ** whether GART support will actually be used, for now we
+ ** can just key on any AGP device found in the system.
+ ** We program the next pdir index after we stop w/ a key for
+ ** the GART code to handshake on.
+ */
+ device=NULL;
+ for (lba = sba->child; lba; lba = lba->sibling) {
+ if (IS_QUICKSILVER(lba))
+ break;
+ }
+
+ if (lba) {
+ DBG_INIT("%s: Reserving half of IOVA space for AGP GART support\n", __FUNCTION__);
+ ioc->pdir_size /= 2;
+ ((u64 *)ioc->pdir_base)[PDIR_INDEX(iova_space_size/2)] = SBA_IOMMU_COOKIE;
+ } else {
+ DBG_INIT("%s: No GART needed - no AGP controller found\n", __FUNCTION__);
+ }
+#endif /* 0 */
+
+}
static void
sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
__FUNCTION__, ioc->ioc_hpa, (int) (physmem>>20),
iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
+ ioc->pdir_base = sba_alloc_pdir(pdir_size);
+
+ DBG_INIT("%s() pdir %p size %x\n",
+ __FUNCTION__, ioc->pdir_base, pdir_size);
+
+#if SBA_HINT_SUPPORT
/* FIXME : DMA HINTs not used */
ioc->hint_shift_pdir = iov_order + PAGE_SHIFT;
ioc->hint_mask_pdir = ~(0x3 << (iov_order + PAGE_SHIFT));
- ioc->pdir_base = sba_alloc_pdir(pdir_size);
-
- DBG_INIT("%s() pdir %p size %x hint_shift_pdir %x hint_mask_pdir %lx\n",
- __FUNCTION__, ioc->pdir_base, pdir_size,
- ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+ DBG_INIT(" hint_shift_pdir %x hint_mask_pdir %lx\n",
+ ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+#endif
ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
WRITE_REG64(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
** On C3000 w/512MB mem, HP-UX 10.20 reports:
** ibase=0, imask=0xFE000000, size=0x2000000.
*/
- ioc->ibase = IOC_IOVA_SPACE_BASE | 1; /* bit 0 == enable bit */
+ ioc->ibase = 0;
ioc->imask = iova_space_mask; /* save it */
+#ifdef ZX1_SUPPORT
+ ioc->iovp_mask = ~(iova_space_mask + PAGE_SIZE - 1);
+#endif
DBG_INIT("%s() IOV base 0x%lx mask 0x%0lx\n",
__FUNCTION__, ioc->ibase, ioc->imask);
/*
** Program the IOC's ibase and enable IOVA translation
*/
- WRITE_REG(ioc->ibase, ioc->ioc_hpa+IOC_IBASE);
+ WRITE_REG(ioc->ibase | 1, ioc->ioc_hpa+IOC_IBASE);
WRITE_REG(ioc->imask, ioc->ioc_hpa+IOC_IMASK);
/* Set I/O PDIR Page size to 4K */
*/
WRITE_REG(0 | 31, ioc->ioc_hpa+IOC_PCOM);
+ ioc->ibase = 0; /* used by SBA_IOVA and related macros */
+
DBG_INIT("%s() DONE\n", __FUNCTION__);
}
*/
}
- ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
- DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
- __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
- ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
- ioc_ctl |= IOC_CTRL_TC; /* Astro: firmware enables this */
+ if (!IS_PLUTO(sba_dev->iodc)) {
+ ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+ DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
+ __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
+ ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
+ ioc_ctl |= IOC_CTRL_TC; /* Astro: firmware enables this */
- WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
+ WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
#ifdef DEBUG_SBA_INIT
- ioc_ctl = READ_REG64(sba_dev->sba_hpa+IOC_CTRL);
- DBG_INIT(" 0x%Lx\n", ioc_ctl);
+ ioc_ctl = READ_REG64(sba_dev->sba_hpa+IOC_CTRL);
+ DBG_INIT(" 0x%Lx\n", ioc_ctl);
#endif
+ } /* if !PLUTO */
if (IS_ASTRO(sba_dev->iodc)) {
/* PAT_PDC (L-class) also reports the same goofy base */
sba_dev->ioc[0].ioc_hpa = ASTRO_IOC_OFFSET;
num_ioc = 1;
+ } else if (IS_PLUTO(sba_dev->iodc)) {
+ /* We use a negative value for IOC HPA so it gets
+ * corrected when we add it with IKE's IOC offset.
+ * Doesnt look clean, but fewer code.
+ */
+ sba_dev->ioc[0].ioc_hpa = -PLUTO_IOC_OFFSET;
+ num_ioc = 1;
} else {
sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0;
num_ioc = 2;
/* flush out the writes */
READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
- sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
+ if (IS_PLUTO(sba_dev->iodc)) {
+ sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
+ } else {
+ sba_ioc_init(sba_dev->dev, &(sba_dev->ioc[i]), i);
+ }
}
}
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_MERCED_PORT, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
{ HPHW_BCPORT, HVERSION_REV_ANY_ID, REOG_MERCED_PORT, 0xc },
+ { HPHW_IOA, HVERSION_REV_ANY_ID, PLUTO_MCKINLEY_PORT, 0xc },
/* These two entries commented out because we don't find them in a
* buswalk yet. If/when we do, they would cause us to think we had
* many more SBAs then we really do.
* { HPHW_BCPORT, HVERSION_REV_ANY_ID, ASTRO_ROPES_PORT, 0xc },
* { HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_ROPES_PORT, 0xc },
+ */
+/* We shall also comment out Pluto Ropes Port since bus walk doesnt
+ * report it yet.
+ * { HPHW_BCPORT, HVERSION_REV_ANY_ID, PLUTO_ROPES_PORT, 0xc },
*/
{ 0, }
};
int i;
char *version;
-#ifdef DEBUG_SBA_INIT
sba_dump_ranges(dev->hpa);
-#endif
/* Read HW Rev First */
func_class = READ_REG(dev->hpa + SBA_FCLASS);
version = astro_rev;
} else if (IS_IKE(&dev->id)) {
- static char ike_rev[]="Ike rev ?";
-
+ static char ike_rev[] = "Ike rev ?";
ike_rev[8] = '0' + (char) (func_class & 0xff);
version = ike_rev;
+ } else if (IS_PLUTO(&dev->id)) {
+ static char pluto_rev[]="Pluto ?.?";
+ pluto_rev[6] = '0' + (char) ((func_class & 0xf0) >> 4);
+ pluto_rev[8] = '0' + (char) (func_class & 0x0f);
+ version = pluto_rev;
} else {
- static char reo_rev[]="REO rev ?";
-
+ static char reo_rev[] = "REO rev ?";
reo_rev[8] = '0' + (char) (func_class & 0xff);
version = reo_rev;
}
if (!global_ioc_cnt) {
global_ioc_cnt = count_parisc_driver(&sba_driver);
- /* Only Astro has one IOC per SBA */
- if (!IS_ASTRO(&dev->id))
+ /* Astro and Pluto have one IOC per SBA */
+ if ((!IS_ASTRO(&dev->id)) || (!IS_PLUTO(&dev->id)))
global_ioc_cnt *= 2;
}
printk(KERN_INFO "%s found %s at 0x%lx\n",
MODULE_NAME, version, dev->hpa);
-#ifdef DEBUG_SBA_INIT
- sba_dump_tlb(dev->hpa);
-#endif
-
sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
if (NULL == sba_dev) {
printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
create_proc_info_entry("Astro", 0, proc_runway_root, sba_proc_info);
} else if (IS_IKE(&dev->id)) {
create_proc_info_entry("Ike", 0, proc_runway_root, sba_proc_info);
+ } else if (IS_PLUTO(&dev->id)) {
+ create_proc_info_entry("Pluto", 0, proc_mckinley_root, sba_proc_info);
} else {
create_proc_info_entry("Reo", 0, proc_runway_root, sba_proc_info);
}
{
#ifdef CONFIG_SERIAL_8250
int retval;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
extern void serial8250_console_init(void); /* drivers/serial/8250.c */
-
+#endif
+
if (!sio_dev.irq_region)
return; /* superio not present */
return;
}
+#ifdef CONFIG_SERIAL_8250_CONSOLE
serial8250_console_init();
-
+#endif
+
serial[1].iobase = sio_dev.sp2_base;
serial[1].irq = sio_dev.irq_region->data.irqbase + SP2_IRQ;
retval = early_serial_setup(&serial[1]);
#include "cirrus.h"
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Driver for the Cirrus PD6729 PCI-PCMCIA bridge");
+MODULE_AUTHOR("Jun Komuro <komurojun@mbn.nifty.com>");
#define MAX_SOCKETS 2
-/* simple helper functions */
-/* External clock time, in nanoseconds. 120 ns = 8.33 MHz */
+/*
+ * simple helper functions
+ * External clock time, in nanoseconds. 120 ns = 8.33 MHz
+ */
#define to_cycles(ns) ((ns)/120)
static spinlock_t port_lock = SPIN_LOCK_UNLOCKED;
*value |= SS_DETECT;
}
- /* IO cards have a different meaning of bits 0,1 */
- /* Also notice the inverse-logic on the bits */
+ /*
+ * IO cards have a different meaning of bits 0,1
+ * Also notice the inverse-logic on the bits
+ */
if (indirect_read(socket, I365_INTCTL) & I365_PC_IOCARD) {
/* IO card */
if (!(status & I365_CS_STSCHG))
state->io_irq = 0;
state->csc_mask = 0;
- /* First the power status of the socket */
- /* PCTRL - Power Control Register */
+ /*
+ * First the power status of the socket
+ * PCTRL - Power Control Register
+ */
reg = indirect_read(socket, I365_POWER);
if (reg & I365_PWR_AUTO)
state->Vpp = 120;
}
- /* Now the IO card, RESET flags and IO interrupt */
- /* IGENC, Interrupt and General Control */
+ /*
+ * Now the IO card, RESET flags and IO interrupt
+ * IGENC, Interrupt and General Control
+ */
reg = indirect_read(socket, I365_INTCTL);
if ((reg & I365_PC_RESET) == 0)
/* Set the IRQ number */
state->io_irq = socket->socket.pci_irq;
- /* Card status change */
- /* CSCICR, Card Status Change Interrupt Configuration */
+ /*
+ * Card status change
+ * CSCICR, Card Status Change Interrupt Configuration
+ */
reg = indirect_read(socket, I365_CSCINT);
if (reg & I365_CSC_DETECT)
printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge at 0x%lx on irq %d\n",
pci_resource_start(dev, 0), dev->irq);
printk(KERN_INFO "pd6729: configured as a %d socket device.\n", MAX_SOCKETS);
- /* Since we have no memory BARs some firmware we may not
- have had PCI_COMMAND_MEM enabled, yet the device needs
- it. */
+ /*
+ * Since we have no memory BARs some firmware we may not
+ * have had PCI_COMMAND_MEM enabled, yet the device needs
+ * it.
+ */
pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
if (!(configbyte & PCI_COMMAND_MEMORY)) {
printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = inode->i_bdev;
- return generic_ide_ioctl(bdev, cmd, arg);
+ return generic_ide_ioctl(file, bdev, cmd, arg);
}
static struct block_device_operations idescsi_ops = {
}
free_irq(host_set->irq, host_set);
- if (host_set->mmio_base)
- iounmap(host_set->mmio_base);
if (host_set->ops->host_stop)
host_set->ops->host_stop(host_set);
+ if (host_set->mmio_base)
+ iounmap(host_set->mmio_base);
for (i = 0; i < host_set->n_ports; i++) {
ap = host_set->ports[i];
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the OSL or the GPL.
*
+ * 0.02
+ * - Added support for CK804 SATA controller.
+ *
+ * 0.01
+ * - Initial revision.
*/
#include <linux/config.h>
#include <linux/libata.h>
#define DRV_NAME "sata_nv"
-#define DRV_VERSION "0.01"
+#define DRV_VERSION "0.02"
#define NV_PORTS 2
#define NV_PIO_MASK 0x1f
#define NV_PORT1_SCR_REG_OFFSET 0x40
#define NV_INT_STATUS 0x10
+#define NV_INT_STATUS_CK804 0x440
#define NV_INT_STATUS_PDEV_INT 0x01
#define NV_INT_STATUS_PDEV_PM 0x02
#define NV_INT_STATUS_PDEV_ADDED 0x04
NV_INT_STATUS_SDEV_HOTPLUG)
#define NV_INT_ENABLE 0x11
+#define NV_INT_ENABLE_CK804 0x441
#define NV_INT_ENABLE_PDEV_MASK 0x01
#define NV_INT_ENABLE_PDEV_PM 0x02
#define NV_INT_ENABLE_PDEV_ADDED 0x04
#define NV_INT_CONFIG 0x12
#define NV_INT_CONFIG_METHD 0x01 // 0 = INT, 1 = SMI
+// For PCI config register 20
+#define NV_MCP_SATA_CFG_20 0x50
+#define NV_MCP_SATA_CFG_20_SATA_SPACE_EN 0x04
+
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void nv_host_stop (struct ata_host_set *host_set);
+static void nv_enable_hotplug(struct ata_probe_ent *probe_ent);
+static void nv_disable_hotplug(struct ata_host_set *host_set);
+static void nv_check_hotplug(struct ata_host_set *host_set);
+static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent);
+static void nv_disable_hotplug_ck804(struct ata_host_set *host_set);
+static void nv_check_hotplug_ck804(struct ata_host_set *host_set);
+
+enum nv_host_type
+{
+ NFORCE2,
+ NFORCE3,
+ CK804
+};
static struct pci_device_id nv_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE3 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
- PCI_ANY_ID, PCI_ANY_ID, },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 },
{ 0, } /* terminate list */
};
+#define NV_HOST_FLAGS_SCR_MMIO 0x00000001
+
+struct nv_host_desc
+{
+ enum nv_host_type host_type;
+ unsigned long host_flags;
+ void (*enable_hotplug)(struct ata_probe_ent *probe_ent);
+ void (*disable_hotplug)(struct ata_host_set *host_set);
+ void (*check_hotplug)(struct ata_host_set *host_set);
+
+};
+static struct nv_host_desc nv_device_tbl[] = {
+ {
+ .host_type = NFORCE2,
+ .host_flags = 0x00000000,
+ .enable_hotplug = nv_enable_hotplug,
+ .disable_hotplug= nv_disable_hotplug,
+ .check_hotplug = nv_check_hotplug,
+ },
+ {
+ .host_type = NFORCE3,
+ .host_flags = 0x00000000,
+ .enable_hotplug = nv_enable_hotplug,
+ .disable_hotplug= nv_disable_hotplug,
+ .check_hotplug = nv_check_hotplug,
+ },
+ { .host_type = CK804,
+ .host_flags = NV_HOST_FLAGS_SCR_MMIO,
+ .enable_hotplug = nv_enable_hotplug_ck804,
+ .disable_hotplug= nv_disable_hotplug_ck804,
+ .check_hotplug = nv_check_hotplug_ck804,
+ },
+};
+
+struct nv_host
+{
+ struct nv_host_desc *host_desc;
+};
+
static struct pci_driver nv_pci_driver = {
.name = DRV_NAME,
.id_table = nv_pci_tbl,
irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
+ struct nv_host *host = host_set->private_data;
unsigned int i;
unsigned int handled = 0;
unsigned long flags;
- u8 intr_status;
- u8 intr_enable;
spin_lock_irqsave(&host_set->lock, flags);
handled += ata_host_intr(ap, qc);
}
- intr_status = inb(ap->ioaddr.scr_addr + NV_INT_STATUS);
- intr_enable = inb(ap->ioaddr.scr_addr + NV_INT_ENABLE);
-
- // Clear interrupt status.
- outb(0xff, ap->ioaddr.scr_addr + NV_INT_STATUS);
-
- if (intr_status & NV_INT_STATUS_HOTPLUG) {
- if (intr_status & NV_INT_STATUS_PDEV_ADDED) {
- printk(KERN_WARNING "ata%u: "
- "Primary device added\n", ap->id);
- }
-
- if (intr_status & NV_INT_STATUS_PDEV_REMOVED) {
- printk(KERN_WARNING "ata%u: "
- "Primary device removed\n", ap->id);
- }
-
- if (intr_status & NV_INT_STATUS_SDEV_ADDED) {
- printk(KERN_WARNING "ata%u: "
- "Secondary device added\n", ap->id);
- }
-
- if (intr_status & NV_INT_STATUS_SDEV_REMOVED) {
- printk(KERN_WARNING "ata%u: "
- "Secondary device removed\n", ap->id);
- }
- }
}
+ if (host->host_desc->check_hotplug)
+ host->host_desc->check_hotplug(host_set);
+
spin_unlock_irqrestore(&host_set->lock, flags);
return IRQ_RETVAL(handled);
static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
+ struct ata_host_set *host_set = ap->host_set;
+ struct nv_host *host = host_set->private_data;
+
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+ if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
+ else
+ return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
+ struct ata_host_set *host_set = ap->host_set;
+ struct nv_host *host = host_set->private_data;
+
if (sc_reg > SCR_CONTROL)
return;
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+ if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+ else
+ outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_host_stop (struct ata_host_set *host_set)
{
- int i;
+ struct nv_host *host = host_set->private_data;
- for (i=0; i<host_set->n_ports; i++) {
- u8 intr_mask;
+ // Disable hotplug event interrupts.
+ if (host->host_desc->disable_hotplug)
+ host->host_desc->disable_hotplug(host_set);
- // Disable hotplug event interrupts.
- intr_mask = inb(host_set->ports[i]->ioaddr.scr_addr +
- NV_INT_ENABLE);
- intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
- outb(intr_mask, host_set->ports[i]->ioaddr.scr_addr +
- NV_INT_ENABLE);
- }
+ kfree(host);
}
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
+ struct nv_host *host;
struct ata_probe_ent *probe_ent = NULL;
- int i;
int rc;
if (!printed_version++)
goto err_out_regions;
}
+ host = kmalloc(sizeof(struct nv_host), GFP_KERNEL);
+ if (!host) {
+ rc = -ENOMEM;
+ goto err_out_free_ent;
+ }
+
+ host->host_desc = &nv_device_tbl[ent->driver_data];
+
memset(probe_ent, 0, sizeof(*probe_ent));
INIT_LIST_HEAD(&probe_ent->node);
ATA_FLAG_SATA_RESET |
ATA_FLAG_SRST |
ATA_FLAG_NO_LEGACY;
+
probe_ent->port_ops = &nv_ops;
probe_ent->n_ports = NV_PORTS;
probe_ent->irq = pdev->irq;
pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
probe_ent->port[0].bmdma_addr =
pci_resource_start(pdev, 4) | NV_PORT0_BMDMA_REG_OFFSET;
- probe_ent->port[0].scr_addr =
- pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET;
probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
ata_std_ports(&probe_ent->port[1]);
pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
probe_ent->port[1].bmdma_addr =
pci_resource_start(pdev, 4) | NV_PORT1_BMDMA_REG_OFFSET;
- probe_ent->port[1].scr_addr =
- pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET;
- pci_set_master(pdev);
+ probe_ent->private_data = host;
- rc = ata_device_add(probe_ent);
- if (rc != NV_PORTS)
- goto err_out_regions;
+ if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO) {
+ unsigned long base;
- // Enable hotplug event interrupts.
- for (i=0; i<probe_ent->n_ports; i++) {
- u8 intr_mask;
+ probe_ent->mmio_base = ioremap(pci_resource_start(pdev, 5),
+ pci_resource_len(pdev, 5));
+ if (probe_ent->mmio_base == NULL)
+ goto err_out_free_ent;
+
+ base = (unsigned long)probe_ent->mmio_base;
- outb(NV_INT_STATUS_HOTPLUG, probe_ent->port[i].scr_addr +
- NV_INT_STATUS);
+ probe_ent->port[0].scr_addr =
+ base + NV_PORT0_SCR_REG_OFFSET;
+ probe_ent->port[1].scr_addr =
+ base + NV_PORT1_SCR_REG_OFFSET;
+ } else {
- intr_mask = inb(probe_ent->port[i].scr_addr + NV_INT_ENABLE);
- intr_mask |= NV_INT_ENABLE_HOTPLUG;
- outb(intr_mask, probe_ent->port[i].scr_addr + NV_INT_ENABLE);
+ probe_ent->port[0].scr_addr =
+ pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET;
+ probe_ent->port[1].scr_addr =
+ pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET;
}
+ pci_set_master(pdev);
+
+ // Enable hotplug event interrupts.
+ if (host->host_desc->enable_hotplug)
+ host->host_desc->enable_hotplug(probe_ent);
+
+ rc = ata_device_add(probe_ent);
+ if (rc != NV_PORTS)
+ goto err_out_free_ent;
+
kfree(probe_ent);
return 0;
+err_out_free_ent:
+ kfree(probe_ent);
+
err_out_regions:
pci_release_regions(pdev);
return rc;
}
+static void nv_enable_hotplug(struct ata_probe_ent *probe_ent)
+{
+ u8 intr_mask;
+
+ outb(NV_INT_STATUS_HOTPLUG,
+ (unsigned long)probe_ent->mmio_base + NV_INT_STATUS);
+
+ intr_mask = inb((unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
+ intr_mask |= NV_INT_ENABLE_HOTPLUG;
+
+ outb(intr_mask, (unsigned long)probe_ent->mmio_base + NV_INT_ENABLE);
+}
+
+static void nv_disable_hotplug(struct ata_host_set *host_set)
+{
+ u8 intr_mask;
+
+ intr_mask = inb((unsigned long)host_set->mmio_base + NV_INT_ENABLE);
+
+ intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
+
+ outb(intr_mask, (unsigned long)host_set->mmio_base + NV_INT_ENABLE);
+}
+
+static void nv_check_hotplug(struct ata_host_set *host_set)
+{
+ u8 intr_status;
+
+ intr_status = inb((unsigned long)host_set->mmio_base + NV_INT_STATUS);
+
+ // Clear interrupt status.
+ outb(0xff, (unsigned long)host_set->mmio_base + NV_INT_STATUS);
+
+ if (intr_status & NV_INT_STATUS_HOTPLUG) {
+ if (intr_status & NV_INT_STATUS_PDEV_ADDED)
+ printk(KERN_WARNING "nv_sata: "
+ "Primary device added\n");
+
+ if (intr_status & NV_INT_STATUS_PDEV_REMOVED)
+ printk(KERN_WARNING "nv_sata: "
+ "Primary device removed\n");
+
+ if (intr_status & NV_INT_STATUS_SDEV_ADDED)
+ printk(KERN_WARNING "nv_sata: "
+ "Secondary device added\n");
+
+ if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
+ printk(KERN_WARNING "nv_sata: "
+ "Secondary device removed\n");
+ }
+}
+
+static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
+{
+ u8 intr_mask;
+ u8 regval;
+
+ pci_read_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, ®val);
+ regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+ pci_write_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, regval);
+
+ writeb(NV_INT_STATUS_HOTPLUG, probe_ent->mmio_base + NV_INT_STATUS_CK804);
+
+ intr_mask = readb(probe_ent->mmio_base + NV_INT_ENABLE_CK804);
+ intr_mask |= NV_INT_ENABLE_HOTPLUG;
+
+ writeb(intr_mask, probe_ent->mmio_base + NV_INT_ENABLE_CK804);
+}
+
+static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
+{
+ u8 intr_mask;
+ u8 regval;
+
+ intr_mask = readb(host_set->mmio_base + NV_INT_ENABLE_CK804);
+
+ intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
+
+ writeb(intr_mask, host_set->mmio_base + NV_INT_ENABLE_CK804);
+
+ pci_read_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, ®val);
+ regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+ pci_write_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, regval);
+}
+
+static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
+{
+ u8 intr_status;
+
+ intr_status = readb(host_set->mmio_base + NV_INT_STATUS_CK804);
+
+ // Clear interrupt status.
+ writeb(0xff, host_set->mmio_base + NV_INT_STATUS_CK804);
+
+ if (intr_status & NV_INT_STATUS_HOTPLUG) {
+ if (intr_status & NV_INT_STATUS_PDEV_ADDED)
+ printk(KERN_WARNING "nv_sata: "
+ "Primary device added\n");
+
+ if (intr_status & NV_INT_STATUS_PDEV_REMOVED)
+ printk(KERN_WARNING "nv_sata: "
+ "Primary device removed\n");
+
+ if (intr_status & NV_INT_STATUS_SDEV_ADDED)
+ printk(KERN_WARNING "nv_sata: "
+ "Secondary device added\n");
+
+ if (intr_status & NV_INT_STATUS_SDEV_REMOVED)
+ printk(KERN_WARNING "nv_sata: "
+ "Secondary device removed\n");
+ }
+}
+
static int __init nv_init(void)
{
return pci_module_init(&nv_pci_driver);
case SCSI_IOCTL_GET_BUS_NUMBER:
return scsi_ioctl(sdp, cmd, p);
default:
- error = scsi_cmd_ioctl(disk, cmd, p);
+ error = scsi_cmd_ioctl(filp, disk, cmd, p);
if (error != -ENOTTY)
return error;
}
case SCSI_IOCTL_GET_BUS_NUMBER:
return scsi_ioctl(sdev, cmd, (void __user *)arg);
}
- return cdrom_ioctl(&cd->cdi, inode, cmd, arg);
+ return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
}
static int sr_block_media_changed(struct gendisk *disk)
case SCSI_IOCTL_GET_BUS_NUMBER:
break;
default:
- i = scsi_cmd_ioctl(STp->disk, cmd_in, p);
+ i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p);
if (i != -ENOTTY)
return i;
break;
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
-#ifdef CONFIG_CIFS_FCNTL
- .fcntl = cifs_fcntl,
-#endif
+ .dir_notify = cifs_dir_notify,
};
struct file_operations cifs_dir_ops = {
.readdir = cifs_readdir,
.release = cifs_closedir,
.read = generic_read_dir,
-#ifdef CONFIG_CIFS_FCNTL
- .fcntl = cifs_fcntl,
-#endif
+ .dir_notify = cifs_dir_notify,
};
static void
extern struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
-extern long cifs_fcntl(int, unsigned int, unsigned long, struct file *);
+extern int cifs_dir_notify(struct file *, unsigned long arg);
/* Functions related to dir entries */
extern struct dentry_operations cifs_dentry_ops;
#include "cifs_unicode.h"
#include "cifs_debug.h"
-int cifs_directory_notify(unsigned long arg, struct file * file)
+int cifs_dir_notify(struct file * file, unsigned long arg)
{
int xid;
int rc = -EINVAL;
FreeXid(xid);
return rc;
}
-
-
-long cifs_fcntl(int file_desc, unsigned int command, unsigned long arg,
- struct file * file)
-{
- /* Few few file control functions need to be specially mapped. So far
- only:
- F_NOTIFY (for directory change notification)
- And eventually:
- F_GETLEASE
- F_SETLEASE
- need to be mapped here. The others either already are mapped downstream
- or do not need to go to the server (client only sideeffects):
- F_DUPFD:
- F_GETFD:
- F_SETFD:
- F_GETFL:
- F_SETFL:
- F_GETLK:
- F_SETLK:
- F_SETLKW:
- F_GETOWN:
- F_SETOWN:
- F_GETSIG:
- F_SETSIG:
- */
- long rc = 0;
-
- cFYI(1,("cifs_fcntl: command %d with arg %lx",command,arg)); /* BB removeme BB */
-
- switch (command) {
- case F_NOTIFY:
- /* let the local call have a chance to fail first */
- rc = generic_file_fcntl(file_desc,command,arg,file);
- if(rc)
- return rc;
- else {
- /* local call succeeded try to do remote notify to
- pick up changes from other clients to server file */
- cifs_directory_notify(arg, file);
- /* BB add case to long and return rc from above */
- return rc;
- }
- break;
- default:
- break;
- }
- return generic_file_fcntl(file_desc,command,arg,file);
-}
-
dn->dn_next = inode->i_dnotify;
inode->i_dnotify = dn;
spin_unlock(&inode->i_lock);
+
+ if (filp->f_op && filp->f_op->dir_notify)
+ return filp->f_op->dir_notify(filp, arg);
return 0;
out_free:
return -EINVAL;
}
+ if (filp->f_op && filp->f_op->check_flags)
+ error = filp->f_op->check_flags(arg);
+ if (error)
+ return error;
+
lock_kernel();
if ((arg ^ filp->f_flags) & FASYNC) {
if (filp->f_op && filp->f_op->fasync) {
EXPORT_SYMBOL(f_delown);
-long generic_file_fcntl(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp)
+static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
+ struct file *filp)
{
long err = -EINVAL;
}
return err;
}
-EXPORT_SYMBOL(generic_file_fcntl);
-
-static long do_fcntl(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp)
-{
- if (filp->f_op && filp->f_op->fcntl)
- return filp->f_op->fcntl(fd, cmd, arg, filp);
- return generic_file_fcntl(fd, cmd, arg, filp);
-}
asmlinkage long sys_fcntl(int fd, unsigned int cmd, unsigned long arg)
{
#define NFSDBG_FACILITY NFSDBG_FILE
-static long nfs_file_fcntl(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp);
static int nfs_file_open(struct inode *, struct file *);
static int nfs_file_release(struct inode *, struct file *);
static int nfs_file_mmap(struct file *, struct vm_area_struct *);
static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t);
static int nfs_file_flush(struct file *);
static int nfs_fsync(struct file *, struct dentry *dentry, int datasync);
+static int nfs_check_flags(int flags);
struct file_operations nfs_file_operations = {
.llseek = remote_llseek,
.fsync = nfs_fsync,
.lock = nfs_lock,
.sendfile = nfs_file_sendfile,
- .fcntl = nfs_file_fcntl,
+ .check_flags = nfs_check_flags,
};
struct inode_operations nfs_file_inode_operations = {
# define IS_SWAPFILE(inode) (0)
#endif
-#define nfs_invalid_flags (O_APPEND | O_DIRECT)
-
-/*
- * Check for special cases that NFS doesn't support, and
- * pass the rest to the generic fcntl function.
- */
-static long
-nfs_file_fcntl(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp)
+static int nfs_check_flags(int flags)
{
- switch (cmd) {
- case F_SETFL:
- if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
- return -EINVAL;
- break;
- default:
- break;
- }
+ if (flags & (O_APPEND | O_DIRECT))
+ return -EINVAL;
- return generic_file_fcntl(fd, cmd, arg, filp);
+ return 0;
}
/*
{
struct nfs_server *server = NFS_SERVER(inode);
int (*open)(struct inode *, struct file *);
- int res = 0;
+ int res;
- if ((filp->f_flags & nfs_invalid_flags) == nfs_invalid_flags)
- return -EINVAL;
+ res = nfs_check_flags(filp->f_flags);
+ if (!res)
+ return res;
lock_kernel();
/* Do NFSv4 open() call */
svc_take_page(rqstp);
args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
+ len -= args->vec[v].iov_len;
v++;
- len -= PAGE_SIZE;
}
args->vlen = v;
return xdr_argsize_check(rqstp, p);
svc_take_page(rqstp);
args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]);
args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
+ len -= args->vec[v].iov_len;
v++;
- len -= PAGE_SIZE;
}
args->vlen = v;
return xdr_argsize_check(rqstp, p);
#define MAX_HWIFS 4
#endif
-#if defined(CONFIG_ARCH_LH7A40X) || defined(CONFIG_ARCH_SA1100)
+#if defined(CONFIG_ARCH_SA1100)
# include <asm/arch/ide.h> /* obsolete + broken */
#endif
-#if !defined(CONFIG_ARCH_L7200) && !defined(CONFIG_ARCH_LH7A40X)
+#if !defined(CONFIG_ARCH_L7200)
# define IDE_ARCH_OBSOLETE_INIT
# ifdef CONFIG_ARCH_CLPS7500
# define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
# else
# define ide_default_io_ctl(base) (0)
# endif
-#endif /* !ARCH_L7200 && !ARCH_LH7A40X */
+#endif /* !ARCH_L7200 */
#define __ide_mm_insw(port,addr,len) readsw(port,addr,len)
#define __ide_mm_insl(port,addr,len) readsl(port,addr,len)
#ifdef __LP64__
#define LDREG ldd
#define STREG std
+#define LDREGX ldd,s
#define LDREGM ldd,mb
#define STREGM std,ma
#define RP_OFFSET 16
#else
#define LDREG ldw
#define STREG stw
+#define LDREGX ldwx,s
#define LDREGM ldwm
#define STREGM stwm
#define RP_OFFSET 20
#define FRAME_SIZE 64
#endif
+#ifdef CONFIG_PA20
+#define BL b,l
+#else
+#define BL bl
+#endif
+
#ifdef __ASSEMBLY__
#ifdef __LP64__
depd,z \r, 63-\sa, 64-\sa, \t
.endm
+ /* Shift Right - note the r and t can NOT be the same! */
+ .macro shr r, sa, t
+ extru \r, 31-\sa, 32-\sa, \t
+ .endm
+
+ /* pa20w version of shift right */
+ .macro shrd r, sa, t
+ extrd,u \r, 63-\sa, 64-\sa, \t
+ .endm
+
/* load 32-bit 'value' into 'reg' compensating for the ldil
* sign-extension when running in wide mode.
* WARNING!! neither 'value' nor 'reg' can be expressions
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
-static __inline__ void set_bit(int nr, void * address)
+static __inline__ void set_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
atomic_spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
}
-static __inline__ void __set_bit(int nr, void * address)
+static __inline__ void __set_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
*addr |= mask;
}
-static __inline__ void clear_bit(int nr, void * address)
+static __inline__ void clear_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
atomic_spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
}
-static __inline__ void __clear_bit(unsigned long nr, volatile void * address)
+static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
*addr &= ~mask;
}
-static __inline__ void change_bit(int nr, void * address)
+static __inline__ void change_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
atomic_spin_unlock_irqrestore(ATOMIC_HASH(addr), flags);
}
-static __inline__ void __change_bit(int nr, void * address)
+static __inline__ void __change_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
*addr ^= mask;
}
-static __inline__ int test_and_set_bit(int nr, void * address)
+static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int __test_and_set_bit(int nr, void * address)
+static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int test_and_clear_bit(int nr, void * address)
+static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int __test_and_clear_bit(int nr, void * address)
+static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int test_and_change_bit(int nr, void * address)
+static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int __test_and_change_bit(int nr, void * address)
+static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address)
{
unsigned long mask;
unsigned long *addr = (unsigned long *) address;
return oldbit;
}
-static __inline__ int test_bit(int nr, const void *address)
+static __inline__ int test_bit(int nr, const volatile unsigned long *address)
{
unsigned long mask;
- unsigned long *addr = (unsigned long *) address;
+ const unsigned long *addr = (const unsigned long *)address;
addr += (nr >> SHIFT_PER_LONG);
mask = 1L << CHOP_SHIFTCOUNT(nr);
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
-static inline int sched_find_first_bit(unsigned long *b)
+static inline int sched_find_first_bit(const unsigned long *b)
{
#ifndef __LP64__
if (unlikely(b[0]))
#define find_first_zero_bit(addr, size) \
find_next_zero_bit((addr), (size), 0)
-static __inline__ unsigned long find_next_zero_bit(void * addr, unsigned long size, unsigned long offset)
+static __inline__ unsigned long find_next_zero_bit(const void * addr, unsigned long size, unsigned long offset)
{
- unsigned long * p = ((unsigned long *) addr) + (offset >> SHIFT_PER_LONG);
+ const unsigned long * p = ((unsigned long *) addr) + (offset >> SHIFT_PER_LONG);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
return result + ffz(tmp);
}
-static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset)
+static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
{
- unsigned long *p = addr + (offset >> 6);
+ const unsigned long *p = addr + (offset >> 6);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
* disabling interrupts.
*/
#ifdef __LP64__
-#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x38, addr)
-#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, addr)
-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x38, addr)
-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, addr)
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
+#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
#else
-#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x18, addr)
-#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, addr)
-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, addr)
-#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, addr)
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
+#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
#endif
#endif /* __KERNEL__ */
#endif
}
-extern void __flush_dcache_page(struct page *page);
-
-static inline void flush_dcache_page(struct page *page)
-{
- struct address_space *mapping = page_mapping(page);
-
- if (mapping && !mapping_mapped(mapping)) {
- set_bit(PG_dcache_dirty, &page->flags);
- } else {
- __flush_dcache_page(page);
- }
-}
+extern void flush_dcache_page(struct page *page);
#define flush_dcache_mmap_lock(mapping) \
spin_lock_irq(&(mapping)->tree_lock)
/* Simple function to work out if we have an existing address translation
* for a user space vma. */
-static inline int translation_exists(struct vm_area_struct *vma,
- unsigned long addr)
+static inline pte_t *__translation_exists(struct mm_struct *mm,
+ unsigned long addr)
{
- pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
+ pgd_t *pgd = pgd_offset(mm, addr);
pmd_t *pmd;
pte_t *pte;
if(pgd_none(*pgd))
- return 0;
+ return NULL;
pmd = pmd_offset(pgd, addr);
if(pmd_none(*pmd) || pmd_bad(*pmd))
- return 0;
+ return NULL;
pte = pte_offset_map(pmd, addr);
/* The PA flush mappings show up as pte_none, but they're
* valid none the less */
if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0))
- return 0;
- return 1;
+ return NULL;
+ return pte;
}
+#define translation_exists(vma, addr) __translation_exists((vma)->vm_mm, addr)
/* Private function to flush a page from the cache of a non-current
#include <linux/mm.h>
#include <linux/config.h>
#include <asm/cacheflush.h>
+#include <asm/scatterlist.h>
/* See Documentation/DMA-mapping.txt */
struct hppa_dma_ops {
#define HPHW_IOA 12
#define HPHW_BRIDGE 13
#define HPHW_FABRIC 14
+#define HPHW_MC 15
#define HPHW_FAULTY 31
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt
-/*
- * Change "struct page" to physical address.
- */
-#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
-
/* Memory mapped IO */
extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
#ifndef _PARISC_MMZONE_H
#define _PARISC_MMZONE_H
+#ifdef CONFIG_DISCONTIGMEM
+
+#define MAX_PHYSMEM_RANGES 8 /* Fix the size for now (current known max is 3) */
+extern int npmem_ranges;
+
struct node_map_data {
pg_data_t pg_data;
- struct page *adj_node_mem_map;
};
extern struct node_map_data node_data[];
-extern unsigned char *chunkmap;
-
-#define BADCHUNK ((unsigned char)0xff)
-#define CHUNKSZ (256*1024*1024)
-#define CHUNKSHIFT 28
-#define CHUNKMASK (~(CHUNKSZ - 1))
-#define CHUNKNUM(paddr) ((paddr) >> CHUNKSHIFT)
#define NODE_DATA(nid) (&node_data[nid].pg_data)
-#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
-#define ADJ_NODE_MEM_MAP(nid) (node_data[nid].adj_node_mem_map)
-#define phys_to_page(paddr) \
- (ADJ_NODE_MEM_MAP(chunkmap[CHUNKNUM((paddr))]) \
- + ((paddr) >> PAGE_SHIFT))
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
+
+#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
+#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid) \
+({ \
+ pg_data_t *__pgdat = NODE_DATA(nid); \
+ __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
+})
+#define node_localnr(pfn, nid) ((pfn) - node_start_pfn(nid))
+
+#define local_mapnr(kvaddr) \
+({ \
+ unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \
+ (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \
+})
+
+#define pfn_to_page(pfn) \
+({ \
+ unsigned long __pfn = (pfn); \
+ int __node = pfn_to_nid(__pfn); \
+ &node_mem_map(__node)[node_localnr(__pfn,__node)]; \
+})
+
+#define page_to_pfn(pg) \
+({ \
+ struct page *__page = pg; \
+ struct zone *__zone = page_zone(__page); \
+ BUG_ON(__zone == NULL); \
+ (unsigned long)(__page - __zone->zone_mem_map) \
+ + __zone->zone_start_pfn; \
+})
+
+/* We have these possible memory map layouts:
+ * Astro: 0-3.75, 67.75-68, 4-64
+ * zx1: 0-1, 257-260, 4-256
+ * Stretch (N-class): 0-2, 4-32, 34-xxx
+ */
+
+/* Since each 1GB can only belong to one region (node), we can create
+ * an index table for pfn to nid lookup; each entry in pfnnid_map
+ * represents 1GB, and contains the node that the memory belongs to. */
+
+#define PFNNID_SHIFT (30 - PAGE_SHIFT)
+#define PFNNID_MAP_MAX 512 /* support 512GB */
+extern unsigned char pfnnid_map[PFNNID_MAP_MAX];
+
+#ifndef __LP64__
+#define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT))
+#else
+/* io can be 0xf0f0f0f0f0xxxxxx or 0xfffffffff0000000 */
+#define pfn_is_io(pfn) ((pfn & (0xf000000000000000UL >> PAGE_SHIFT)) == (0xf000000000000000UL >> PAGE_SHIFT))
+#endif
+
+static inline int pfn_to_nid(unsigned long pfn)
+{
+ unsigned int i;
+ unsigned char r;
+
+ if (unlikely(pfn_is_io(pfn)))
+ return 0;
+
+ i = pfn >> PFNNID_SHIFT;
+ BUG_ON(i >= sizeof(pfnnid_map) / sizeof(pfnnid_map[0]));
+ r = pfnnid_map[i];
+ BUG_ON(r == 0xff);
+
+ return (int)r;
+}
-#define virt_to_page(kvaddr) phys_to_page(__pa(kvaddr))
+static inline int pfn_valid(int pfn)
+{
+ int nid = pfn_to_nid(pfn);
-/* This is kind of bogus, need to investigate performance of doing it right */
-#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
+ if (nid >= 0)
+ return (pfn < node_end_pfn(nid));
+ return 0;
+}
-#endif /* !_PARISC_MMZONE_H */
+#else /* !CONFIG_DISCONTIGMEM */
+#define MAX_PHYSMEM_RANGES 1
+#endif
+#endif /* _PARISC_MMZONE_H */
#else
#define pte_flags(x) ((x).flags)
#endif
-#define pmd_val(x) ((x).pmd)
-#define pgd_val(x) ((x).pgd)
+
+/* These do not work lvalues, so make sure we don't use them as such. */
+#define pmd_val(x) ((x).pmd + 0)
+#define pgd_val(x) ((x).pgd + 0)
#define pgprot_val(x) ((x).pgprot)
+#define __pmd_val_set(x,n) (x).pmd = (n)
+#define __pgd_val_set(x,n) (x).pgd = (n)
+
#define __pte(x) ((pte_t) { (x) } )
#define __pmd(x) ((pmd_t) { (x) } )
#define __pgd(x) ((pgd_t) { (x) } )
return order;
}
-#ifdef __LP64__
-#define MAX_PHYSMEM_RANGES 8 /* Fix the size for now (current known max is 3) */
-#else
-#define MAX_PHYSMEM_RANGES 1 /* First range is only range that fits in 32 bits */
-#endif
-
typedef struct __physmem_range {
unsigned long start_pfn;
unsigned long pages; /* PAGE_SIZE pages */
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
+#ifndef CONFIG_DISCONTIGMEM
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#define pfn_valid(pfn) ((pfn) < max_mapnr)
+#endif /* CONFIG_DISCONTIGMEM */
+
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-#ifndef CONFIG_DISCONTIGMEM
-#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
-#endif /* !CONFIG_DISCONTIGMEM */
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
*/
#define PCI_MAX_BUSSES 256
-/* [soapbox on]
-** Who the hell can develop stuff without ASSERT or VASSERT?
-** No one understands all the modules across all platforms.
-** For linux add another dimension - processor architectures.
-**
-** This should be a standard/global macro used liberally
-** in all code. Every respectable engineer I know in HP
-** would support this argument. - grant
-** [soapbox off]
-*/
-#ifdef PCI_DEBUG
-#define ASSERT(expr) \
- if(!(expr)) { \
- printk("\n%s:%d: Assertion " #expr " failed!\n", \
- __FILE__, __LINE__); \
- panic(#expr); \
- }
-#else
-#define ASSERT(expr)
-#endif
-
-
/*
** pci_hba_data (aka H2P_OBJECT in HP/UX)
**
#define OSTAT_RUN 6
#define OSTAT_ON 7
-#ifdef __LP64__
-/* PDC PAT CELL */
-#define PDC_PAT_CELL 64L /* Interface for gaining and
- * manipulating cell state within PD */
-#define PDC_PAT_CELL_GET_NUMBER 0L /* Return Cell number */
-#define PDC_PAT_CELL_GET_INFO 1L /* Returns info about Cell */
-#define PDC_PAT_CELL_MODULE 2L /* Returns info about Module */
-#define PDC_PAT_CELL_SET_ATTENTION 9L /* Set Cell Attention indicator */
-#define PDC_PAT_CELL_NUMBER_TO_LOC 10L /* Cell Number -> Location */
-#define PDC_PAT_CELL_WALK_FABRIC 11L /* Walk the Fabric */
-#define PDC_PAT_CELL_GET_RDT_SIZE 12L /* Return Route Distance Table Sizes */
-#define PDC_PAT_CELL_GET_RDT 13L /* Return Route Distance Tables */
-#define PDC_PAT_CELL_GET_LOCAL_PDH_SZ 14L /* Read Local PDH Buffer Size*/
-#define PDC_PAT_CELL_SET_LOCAL_PDH 15L /* Write Local PDH Buffer */
-#define PDC_PAT_CELL_GET_REMOTE_PDH_SZ 16L /* Return Remote PDH Buffer Size */
-#define PDC_PAT_CELL_GET_REMOTE_PDH 17L /* Read Remote PDH Buffer */
-#define PDC_PAT_CELL_GET_DBG_INFO 128L /* Return DBG Buffer Info */
-#define PDC_PAT_CELL_CHANGE_ALIAS 129L /* Change Non-Equivalent Alias Checking */
-
-/*
-** Arg to PDC_PAT_CELL_MODULE memaddr[4]
-**
-** Addresses on the Merced Bus != all Runway Bus addresses.
-** This is intended for programming SBA/LBA chips range registers.
-*/
-#define IO_VIEW 0UL
-#define PA_VIEW 1UL
-
-/* PDC_PAT_CELL_MODULE entity type values */
-#define PAT_ENTITY_CA 0 /* central agent */
-#define PAT_ENTITY_PROC 1 /* processor */
-#define PAT_ENTITY_MEM 2 /* memory controller */
-#define PAT_ENTITY_SBA 3 /* system bus adapter */
-#define PAT_ENTITY_LBA 4 /* local bus adapter */
-#define PAT_ENTITY_PBC 5 /* processor bus converter */
-#define PAT_ENTITY_XBC 6 /* crossbar fabric connect */
-#define PAT_ENTITY_RC 7 /* fabric interconnect */
-
-/* PDC_PAT_CELL_MODULE address range type values */
-#define PAT_PBNUM 0 /* PCI Bus Number */
-#define PAT_LMMIO 1 /* < 4G MMIO Space */
-#define PAT_GMMIO 2 /* > 4G MMIO Space */
-#define PAT_NPIOP 3 /* Non Postable I/O Port Space */
-#define PAT_PIOP 4 /* Postable I/O Port Space */
-#define PAT_AHPA 5 /* Additional HPA Space */
-#define PAT_UFO 6 /* HPA Space (UFO for Mariposa) */
-#define PAT_GNIP 7 /* GNI Reserved Space */
-
-
-/* PDC PAT CHASSIS LOG */
-#define PDC_PAT_CHASSIS_LOG 65L /* Platform logging & forward
- ** progress functions */
-#define PDC_PAT_CHASSIS_WRITE_LOG 0L /* Write Log Entry */
-#define PDC_PAT_CHASSIS_READ_LOG 1L /* Read Log Entry */
-
-
-/* PDC PAT CPU */
-#define PDC_PAT_CPU 67L /* Interface to CPU configuration
- * within the protection domain */
-#define PDC_PAT_CPU_INFO 0L /* Return CPU config info */
-#define PDC_PAT_CPU_DELETE 1L /* Delete CPU */
-#define PDC_PAT_CPU_ADD 2L /* Add CPU */
-#define PDC_PAT_CPU_GET_NUMBER 3L /* Return CPU Number */
-#define PDC_PAT_CPU_GET_HPA 4L /* Return CPU HPA */
-#define PDC_PAT_CPU_STOP 5L /* Stop CPU */
-#define PDC_PAT_CPU_RENDEZVOUS 6L /* Rendezvous CPU */
-#define PDC_PAT_CPU_GET_CLOCK_INFO 7L /* Return CPU Clock info */
-#define PDC_PAT_CPU_GET_RENDEZVOUS_STATE 8L /* Return Rendezvous State */
-#define PDC_PAT_CPU_PLUNGE_FABRIC 128L /* Plunge Fabric */
-#define PDC_PAT_CPU_UPDATE_CACHE_CLEANSING 129L /* Manipulate Cache
- * Cleansing Mode */
-
-/* PDC PAT EVENT */
-#define PDC_PAT_EVENT 68L /* Interface to Platform Events */
-#define PDC_PAT_EVENT_GET_CAPS 0L /* Get Capabilities */
-#define PDC_PAT_EVENT_SET_MODE 1L /* Set Notification Mode */
-#define PDC_PAT_EVENT_SCAN 2L /* Scan Event */
-#define PDC_PAT_EVENT_HANDLE 3L /* Handle Event */
-#define PDC_PAT_EVENT_GET_NB_CALL 4L /* Get Non-Blocking call Args*/
-
-/* PDC PAT HPMC */
-#define PDC_PAT_HPMC 70L /* Cause processor to go into spin
- ** loop, and wait for wake up from
- ** Monarch Processor */
-#define PDC_PAT_HPMC_RENDEZ_CPU 0L /* go into spin loop */
-#define PDC_PAT_HPMC_SET_PARAMS 1L /* Allows OS to specify intr which PDC
- * will use to interrupt OS during machine
- * check rendezvous */
-
-/* parameters for PDC_PAT_HPMC_SET_PARAMS */
-#define HPMC_SET_PARAMS_INTR 1L /* Rendezvous Interrupt */
-#define HPMC_SET_PARAMS_WAKE 2L /* Wake up processor */
-
-/* PDC PAT IO */
-#define PDC_PAT_IO 71L /* On-line services for I/O modules */
-#define PDC_PAT_IO_GET_SLOT_STATUS 5L /* Get Slot Status Info */
-#define PDC_PAT_IO_GET_LOC_FROM_HARDWARE 6L /* Get Physical Location from */
- /* Hardware Path */
-#define PDC_PAT_IO_GET_HARDWARE_FROM_LOC 7L /* Get Hardware Path from
- * Physical Location */
-#define PDC_PAT_IO_GET_PCI_CONFIG_FROM_HW 11L /* Get PCI Configuration
- * Address from Hardware Path */
-#define PDC_PAT_IO_GET_HW_FROM_PCI_CONFIG 12L /* Get Hardware Path
- * from PCI Configuration Address */
-#define PDC_PAT_IO_READ_HOST_BRIDGE_INFO 13L /* Read Host Bridge State Info */
-#define PDC_PAT_IO_CLEAR_HOST_BRIDGE_INFO 14L /* Clear Host Bridge State Info*/
-#define PDC_PAT_IO_GET_PCI_ROUTING_TABLE_SIZE 15L /* Get PCI INT Routing Table
- * Size */
-#define PDC_PAT_IO_GET_PCI_ROUTING_TABLE 16L /* Get PCI INT Routing Table */
-#define PDC_PAT_IO_GET_HINT_TABLE_SIZE 17L /* Get Hint Table Size */
-#define PDC_PAT_IO_GET_HINT_TABLE 18L /* Get Hint Table */
-#define PDC_PAT_IO_PCI_CONFIG_READ 19L /* PCI Config Read */
-#define PDC_PAT_IO_PCI_CONFIG_WRITE 20L /* PCI Config Write */
-#define PDC_PAT_IO_GET_NUM_IO_SLOTS 21L /* Get Number of I/O Bay Slots in
- * Cabinet */
-#define PDC_PAT_IO_GET_LOC_IO_SLOTS 22L /* Get Physical Location of I/O */
- /* Bay Slots in Cabinet */
-#define PDC_PAT_IO_BAY_STATUS_INFO 28L /* Get I/O Bay Slot Status Info */
-#define PDC_PAT_IO_GET_PROC_VIEW 29L /* Get Processor view of IO address */
-#define PDC_PAT_IO_PROG_SBA_DIR_RANGE 30L /* Program directed range */
-
-/* PDC PAT MEM */
-#define PDC_PAT_MEM 72L /* Manage memory page deallocation */
-#define PDC_PAT_MEM_PD_INFO 0L /* Return PDT info for PD */
-#define PDC_PAT_MEM_PD_CLEAR 1L /* Clear PDT for PD */
-#define PDC_PAT_MEM_PD_READ 2L /* Read PDT entries for PD */
-#define PDC_PAT_MEM_PD_RESET 3L /* Reset clear bit for PD */
-#define PDC_PAT_MEM_CELL_INFO 5L /* Return PDT info For Cell */
-#define PDC_PAT_MEM_CELL_CLEAR 6L /* Clear PDT For Cell */
-#define PDC_PAT_MEM_CELL_READ 7L /* Read PDT entries For Cell */
-#define PDC_PAT_MEM_CELL_RESET 8L /* Reset clear bit For Cell */
-#define PDC_PAT_MEM_SETGM 9L /* Set Golden Memory value */
-#define PDC_PAT_MEM_ADD_PAGE 10L /* ADDs a page to the cell */
-#define PDC_PAT_MEM_ADDRESS 11L /* Get Physical Location From*/
- /* Memory Address */
-#define PDC_PAT_MEM_GET_TXT_SIZE 12L /* Get Formatted Text Size */
-#define PDC_PAT_MEM_GET_PD_TXT 13L /* Get PD Formatted Text */
-#define PDC_PAT_MEM_GET_CELL_TXT 14L /* Get Cell Formatted Text */
-#define PDC_PAT_MEM_RD_STATE_INFO 15L /* Read Mem Module State Info*/
-#define PDC_PAT_MEM_CLR_STATE_INFO 16L /*Clear Mem Module State Info*/
-#define PDC_PAT_MEM_CLEAN_RANGE 128L /*Clean Mem in specific range*/
-#define PDC_PAT_MEM_GET_TBL_SIZE 131L /* Get Memory Table Size */
-#define PDC_PAT_MEM_GET_TBL 132L /* Get Memory Table */
-
-/* PDC PAT NVOLATILE */
-#define PDC_PAT_NVOLATILE 73L /* Access Non-Volatile Memory*/
-#define PDC_PAT_NVOLATILE_READ 0L /* Read Non-Volatile Memory */
-#define PDC_PAT_NVOLATILE_WRITE 1L /* Write Non-Volatile Memory */
-#define PDC_PAT_NVOLATILE_GET_SIZE 2L /* Return size of NVM */
-#define PDC_PAT_NVOLATILE_VERIFY 3L /* Verify contents of NVM */
-#define PDC_PAT_NVOLATILE_INIT 4L /* Initialize NVM */
-
-/* PDC PAT PD */
-#define PDC_PAT_PD 74L /* Protection Domain Info */
-#define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */
-
-/* PDC_PAT_PD_GET_ADDR_MAP entry types */
-#define PAT_MEMORY_DESCRIPTOR 1
-
-/* PDC_PAT_PD_GET_ADDR_MAP memory types */
-#define PAT_MEMTYPE_MEMORY 0
-#define PAT_MEMTYPE_FIRMWARE 4
-
-/* PDC_PAT_PD_GET_ADDR_MAP memory usage */
-#define PAT_MEMUSE_GENERAL 0
-#define PAT_MEMUSE_GI 128
-#define PAT_MEMUSE_GNI 129
-#endif /* __LP64__ */
-
#ifndef __ASSEMBLY__
#include <linux/types.h>
#define PDC_TYPE_SYSTEM_MAP 1 /* 32-bit, but supports PDC_SYSTEM_MAP */
#define PDC_TYPE_SNAKE 2 /* Doesn't support SYSTEM_MAP */
-#ifdef CONFIG_PARISC64
-#define is_pdc_pat() (PDC_TYPE_PAT == pdc_type)
-#else
-#define is_pdc_pat() (0)
-#endif
-
struct pdc_chassis_info { /* for PDC_CHASSIS_INFO */
unsigned long actcnt; /* actual number of bytes returned */
unsigned long maxcnt; /* maximum number of bytes that could be returned */
#ifdef __LP64__
cc_padW:32,
#endif
- cc_alias:4, /* alias boundaries for virtual addresses */
+ cc_alias: 4, /* alias boundaries for virtual addresses */
cc_block: 4, /* to determine most efficient stride */
cc_line : 3, /* maximum amount written back as a result of store (multiple of 16 bytes) */
- cc_pad0 : 2, /* reserved */
+ cc_shift: 2, /* how much to shift cc_block left */
cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
unsigned long tod_usec;
};
-#ifdef __LP64__
-struct pdc_pat_cell_num {
- unsigned long cell_num;
- unsigned long cell_loc;
-};
-
-struct pdc_pat_cpu_num {
- unsigned long cpu_num;
- unsigned long cpu_loc;
-};
-
-struct pdc_pat_pd_addr_map_entry {
- unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */
- unsigned char reserve1[5];
- unsigned char memory_type;
- unsigned char memory_usage;
- unsigned long paddr;
- unsigned int pages; /* Length in 4K pages */
- unsigned int reserve2;
- unsigned long cell_map;
-};
-
-/* FIXME: mod[508] should really be a union of the various mod components */
-struct pdc_pat_cell_mod_maddr_block { /* PDC_PAT_CELL_MODULE */
- unsigned long cba; /* function 0 configuration space address */
- unsigned long mod_info; /* module information */
- unsigned long mod_location; /* physical location of the module */
- struct hardware_path mod_path; /* hardware path */
- unsigned long mod[508]; /* PAT cell module components */
-};
-
-typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;
-#endif /* __LP64__ */
-
/* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
struct pdc_hpmc_pim_11 { /* PDC_PIM */
unsigned long inptr, unsigned long outputr,
unsigned long glob_cfg);
-#ifdef __LP64__
-int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
-int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
-int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod,
- unsigned long view_type, void *mem_addr);
-int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa);
-int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num);
-int pdc_pat_get_irt(void *r_addr, unsigned long cell_num);
-int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr,
- unsigned long count, unsigned long offset);
-
-/********************************************************************
-* PDC_PAT_CELL[Return Cell Module] memaddr[0] conf_base_addr
-* ----------------------------------------------------------
-* Bit 0 to 51 - conf_base_addr
-* Bit 52 to 62 - reserved
-* Bit 63 - endianess bit
-********************************************************************/
-#define PAT_GET_CBA(value) ((value) & 0xfffffffffffff000UL)
-
-/********************************************************************
-* PDC_PAT_CELL[Return Cell Module] memaddr[1] mod_info
-* ----------------------------------------------------
-* Bit 0 to 7 - entity type
-* 0 = central agent, 1 = processor,
-* 2 = memory controller, 3 = system bus adapter,
-* 4 = local bus adapter, 5 = processor bus converter,
-* 6 = crossbar fabric connect, 7 = fabric interconnect,
-* 8 to 254 reserved, 255 = unknown.
-* Bit 8 to 15 - DVI
-* Bit 16 to 23 - IOC functions
-* Bit 24 to 39 - reserved
-* Bit 40 to 63 - mod_pages
-* number of 4K pages a module occupies starting at conf_base_addr
-********************************************************************/
-#define PAT_GET_ENTITY(value) (((value) >> 56) & 0xffUL)
-#define PAT_GET_DVI(value) (((value) >> 48) & 0xffUL)
-#define PAT_GET_IOC(value) (((value) >> 40) & 0xffUL)
-#define PAT_GET_MOD_PAGES(value)(((value) & 0xffffffUL)
-
-#else /* !__LP64__ */
-/* No PAT support for 32-bit kernels...sorry */
-#define pdc_pat_get_irt_size(num_entries, cell_numn) PDC_BAD_PROC
-#define pdc_pat_get_irt(r_addr, cell_num) PDC_BAD_PROC
-#endif /* !__LP64__ */
-
extern void pdc_init(void);
#endif /* __ASSEMBLY__ */
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (c) Hewlett Packard (Paul Bame <bame@puffin.external.hp.com>)
- * Copyright 2000 (c) Grant Grundler <grundler@puffin.external.hp.com>
+ * Copyright 2000 (c) Hewlett Packard (Paul Bame <bame()spam.parisc-linux.org>)
+ * Copyright 2000,2004 (c) Grant Grundler <grundler()nahspam.parisc-linux.org>
*/
-/* PDC PAT CELL */
#define PDC_PAT_CELL 64L /* Interface for gaining and
* manipulatin g cell state within PD */
#define PDC_PAT_CELL_GET_NUMBER 0L /* Return Cell number */
#define PAT_GNIP 7 /* GNI Reserved Space */
-/* PDC PAT CHASSIS LOG */
-#define PDC_PAT_CHASSIS_LOG 65L /* Platform logging & forward
- ** progress functions */
+/* PDC PAT CHASSIS LOG -- Platform logging & forward progress functions */
+
+#define PDC_PAT_CHASSIS_LOG 65L
#define PDC_PAT_CHASSIS_WRITE_LOG 0L /* Write Log Entry */
#define PDC_PAT_CHASSIS_READ_LOG 1L /* Read Log Entry */
-/* PDC PAT CPU */
-#define PDC_PAT_CPU 67L /* Interface to CPU configuration
- * within the protection domain */
+/* PDC PAT CPU -- CPU configuration within the protection domain */
+
+#define PDC_PAT_CPU 67L
#define PDC_PAT_CPU_INFO 0L /* Return CPU config info */
#define PDC_PAT_CPU_DELETE 1L /* Delete CPU */
#define PDC_PAT_CPU_ADD 2L /* Add CPU */
#define PDC_PAT_CPU_PLUNGE_FABRIC 128L /* Plunge Fabric */
#define PDC_PAT_CPU_UPDATE_CACHE_CLEANSING 129L /* Manipulate Cache
* Cleansing Mode */
-/* PDC PAT EVENT */
+/* PDC PAT EVENT -- Platform Events */
-#define PDC_PAT_EVENT 68L /* Interface to Platform Events */
+#define PDC_PAT_EVENT 68L
#define PDC_PAT_EVENT_GET_CAPS 0L /* Get Capabilities */
#define PDC_PAT_EVENT_SET_MODE 1L /* Set Notification Mode */
#define PDC_PAT_EVENT_SCAN 2L /* Scan Event */
#define PDC_PAT_EVENT_HANDLE 3L /* Handle Event */
#define PDC_PAT_EVENT_GET_NB_CALL 4L /* Get Non-Blocking call Args */
-/* PDC PAT HPMC */
+/* PDC PAT HPMC -- Cause processor to go into spin loop, and wait
+ * for wake up from Monarch Processor.
+ */
-#define PDC_PAT_HPMC 70L /* Cause processor to go into spin
- ** loop, and wait for wake up from
- ** Monarch Processor */
+#define PDC_PAT_HPMC 70L
#define PDC_PAT_HPMC_RENDEZ_CPU 0L /* go into spin loop */
#define PDC_PAT_HPMC_SET_PARAMS 1L /* Allows OS to specify intr which PDC
- * will use to interrupt OS during machine
- * check rendezvous */
+ * will use to interrupt OS during
+ * machine check rendezvous */
/* parameters for PDC_PAT_HPMC_SET_PARAMS: */
#define HPMC_SET_PARAMS_INTR 1L /* Rendezvous Interrupt */
#define HPMC_SET_PARAMS_WAKE 2L /* Wake up processor */
-/* PDC PAT IO */
-#define PDC_PAT_IO 71L /* On-line services for I/O modules */
+/* PDC PAT IO -- On-line services for I/O modules */
+
+#define PDC_PAT_IO 71L
#define PDC_PAT_IO_GET_SLOT_STATUS 5L /* Get Slot Status Info*/
#define PDC_PAT_IO_GET_LOC_FROM_HARDWARE 6L /* Get Physical Location from */
/* Hardware Path */
#define PDC_PAT_IO_GET_PROC_VIEW 29L /* Get Processor view of IO address */
#define PDC_PAT_IO_PROG_SBA_DIR_RANGE 30L /* Program directed range */
-/* PDC PAT MEM */
-#define PDC_PAT_MEM 72L /* Manage memory page deallocation */
+/* PDC PAT MEM -- Manage memory page deallocation */
+
+#define PDC_PAT_MEM 72L
#define PDC_PAT_MEM_PD_INFO 0L /* Return PDT info for PD */
#define PDC_PAT_MEM_PD_CLEAR 1L /* Clear PDT for PD */
#define PDC_PAT_MEM_PD_READ 2L /* Read PDT entries for PD */
#define PDC_PAT_MEM_GET_TBL_SIZE 131L /* Get Memory Table Size */
#define PDC_PAT_MEM_GET_TBL 132L /* Get Memory Table */
-/* PDC PAT NVOLATILE */
-#define PDC_PAT_NVOLATILE 73L /* Access Non-Volatile Memory */
-#define PDC_PAT_NVOLATILE_READ 0L /* Read Non-Volatile Memory */
-#define PDC_PAT_NVOLATILE_WRITE 1L /* Write Non-Volatile Memory */
-#define PDC_PAT_NVOLATILE_GET_SIZE 2L /* Return size of NVM */
-#define PDC_PAT_NVOLATILE_VERIFY 3L /* Verify contents of NVM */
-#define PDC_PAT_NVOLATILE_INIT 4L /* Initialize NVM */
+/* PDC PAT NVOLATILE -- Access Non-Volatile Memory */
+
+#define PDC_PAT_NVOLATILE 73L
+#define PDC_PAT_NVOLATILE_READ 0L /* Read Non-Volatile Memory */
+#define PDC_PAT_NVOLATILE_WRITE 1L /* Write Non-Volatile Memory */
+#define PDC_PAT_NVOLATILE_GET_SIZE 2L /* Return size of NVM */
+#define PDC_PAT_NVOLATILE_VERIFY 3L /* Verify contents of NVM */
+#define PDC_PAT_NVOLATILE_INIT 4L /* Initialize NVM */
+
+/* PDC PAT PD */
+#define PDC_PAT_PD 74L /* Protection Domain Info */
+#define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */
+
+/* PDC_PAT_PD_GET_ADDR_MAP entry types */
+#define PAT_MEMORY_DESCRIPTOR 1
+
+/* PDC_PAT_PD_GET_ADDR_MAP memory types */
+#define PAT_MEMTYPE_MEMORY 0
+#define PAT_MEMTYPE_FIRMWARE 4
+
+/* PDC_PAT_PD_GET_ADDR_MAP memory usage */
+#define PAT_MEMUSE_GENERAL 0
+#define PAT_MEMUSE_GI 128
+#define PAT_MEMUSE_GNI 129
+
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#ifdef CONFIG_PARISC64
+#define is_pdc_pat() (PDC_TYPE_PAT == pdc_type)
+extern int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num);
+extern int pdc_pat_get_irt(void *r_addr, unsigned long cell_num);
+#else /* ! CONFIG_PARISC64 */
+/* No PAT support for 32-bit kernels...sorry */
+#define is_pdc_pat() (0)
+#define pdc_pat_get_irt_size(num_entries, cell_numn) PDC_BAD_PROC
+#define pdc_pat_get_irt(r_addr, cell_num) PDC_BAD_PROC
+#endif /* ! CONFIG_PARISC64 */
+
+
+struct pdc_pat_cell_num {
+ unsigned long cell_num;
+ unsigned long cell_loc;
+};
+
+struct pdc_pat_cpu_num {
+ unsigned long cpu_num;
+ unsigned long cpu_loc;
+};
+
+struct pdc_pat_pd_addr_map_entry {
+ unsigned char entry_type; /* 1 = Memory Descriptor Entry Type */
+ unsigned char reserve1[5];
+ unsigned char memory_type;
+ unsigned char memory_usage;
+ unsigned long paddr;
+ unsigned int pages; /* Length in 4K pages */
+ unsigned int reserve2;
+ unsigned long cell_map;
+};
+
+/********************************************************************
+* PDC_PAT_CELL[Return Cell Module] memaddr[0] conf_base_addr
+* ----------------------------------------------------------
+* Bit 0 to 51 - conf_base_addr
+* Bit 52 to 62 - reserved
+* Bit 63 - endianess bit
+********************************************************************/
+#define PAT_GET_CBA(value) ((value) & 0xfffffffffffff000UL)
+
+/********************************************************************
+* PDC_PAT_CELL[Return Cell Module] memaddr[1] mod_info
+* ----------------------------------------------------
+* Bit 0 to 7 - entity type
+* 0 = central agent, 1 = processor,
+* 2 = memory controller, 3 = system bus adapter,
+* 4 = local bus adapter, 5 = processor bus converter,
+* 6 = crossbar fabric connect, 7 = fabric interconnect,
+* 8 to 254 reserved, 255 = unknown.
+* Bit 8 to 15 - DVI
+* Bit 16 to 23 - IOC functions
+* Bit 24 to 39 - reserved
+* Bit 40 to 63 - mod_pages
+* number of 4K pages a module occupies starting at conf_base_addr
+********************************************************************/
+#define PAT_GET_ENTITY(value) (((value) >> 56) & 0xffUL)
+#define PAT_GET_DVI(value) (((value) >> 48) & 0xffUL)
+#define PAT_GET_IOC(value) (((value) >> 40) & 0xffUL)
+#define PAT_GET_MOD_PAGES(value)(((value) & 0xffffffUL)
+
+
/*
** PDC_PAT_CELL_GET_INFO return block
*/
/* FIXME: mod[508] should really be a union of the various mod components */
struct pdc_pat_cell_mod_maddr_block { /* PDC_PAT_CELL_MODULE */
- unsigned long cba; /* function 0 configuration space address */
- unsigned long mod_info; /* module information */
- unsigned long mod_location; /* physical location of the module */
- unsigned long mod_path; /* module path (device path - layers) */
+ unsigned long cba; /* func 0 cfg space address */
+ unsigned long mod_info; /* module information */
+ unsigned long mod_location; /* physical location of the module */
+ struct hardware_path mod_path; /* module path (device path - layers) */
unsigned long mod[508]; /* PAT cell module components */
} __attribute__((aligned(8))) ;
typedef struct pdc_pat_cell_mod_maddr_block pdc_pat_cell_mod_maddr_block_t;
-extern int pdc_pat_cell_get_number(void *);
-extern int pdc_pat_cell_module(void *, unsigned long, unsigned long, unsigned long, void *);
+extern int pdc_pat_chassis_send_log(unsigned long status, unsigned long data);
+extern int pdc_pat_cell_get_number(struct pdc_pat_cell_num *cell_info);
+extern int pdc_pat_cell_module(unsigned long *actcnt, unsigned long ploc, unsigned long mod, unsigned long view_type, void *mem_addr);
extern int pdc_pat_cell_num_to_loc(void *, unsigned long);
+extern int pdc_pat_cpu_get_number(struct pdc_pat_cpu_num *cpu_info, void *hpa);
+
+extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset);
+
+
+extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val);
+extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val);
+
+
/* Flag to indicate this is a PAT box...don't use this unless you
** really have to...it might go away some day.
*/
-#ifdef __LP64__
extern int pdc_pat; /* arch/parisc/kernel/inventory.c */
-#endif
/********************************************************************
* PDC_PAT_CELL[Return Cell Module] memaddr[0] conf_base_addr
* kernel for machines with under 4GB of memory) */
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
- pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|GFP_DMA,
+ pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,
PGD_ALLOC_ORDER);
pgd_t *actual_pgd = pgd;
#ifdef __LP64__
actual_pgd += PTRS_PER_PGD;
/* Populate first pmd with allocated memory. We mark it
- * with _PAGE_GATEWAY as a signal to the system that this
+ * with PxD_FLAG_ATTACHED as a signal to the system that this
* pmd entry may not be cleared. */
- pgd_val(*actual_pgd) = (_PAGE_TABLE | _PAGE_GATEWAY) +
- (__u32)__pa((unsigned long)pgd);
+ __pgd_val_set(*actual_pgd, (PxD_FLAG_PRESENT |
+ PxD_FLAG_VALID |
+ PxD_FLAG_ATTACHED)
+ + (__u32)(__pa((unsigned long)pgd) >> PxD_VALUE_SHIFT));
/* The first pmd entry also is marked with _PAGE_GATEWAY as
* a signal that this pmd may not be freed */
- pgd_val(*pgd) = _PAGE_GATEWAY;
+ __pgd_val_set(*pgd, PxD_FLAG_ATTACHED);
#endif
}
return actual_pgd;
static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
{
- pgd_val(*pgd) = _PAGE_TABLE + (__u32)__pa((unsigned long)pmd);
+ __pgd_val_set(*pgd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
+ (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
}
-/* NOTE: pmd must be in ZONE_DMA (<4GB) so the pgd pointer can be
- * housed in 32 bits */
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
{
- pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT|GFP_DMA,
+ pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT,
PMD_ORDER);
if (pmd)
memset(pmd, 0, PAGE_SIZE<<PMD_ORDER);
static inline void pmd_free(pmd_t *pmd)
{
#ifdef __LP64__
- if(pmd_val(*pmd) & _PAGE_GATEWAY)
+ if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
/* This is the permanent pmd attached to the pgd;
* cannot free it */
return;
#ifdef __LP64__
/* preserve the gateway marker if this is the beginning of
* the permanent pmd */
- if(pmd_val(*pmd) & _PAGE_GATEWAY)
- pmd_val(*pmd) = (_PAGE_TABLE | _PAGE_GATEWAY)
- + (__u32)__pa((unsigned long)pte);
+ if(pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
+ __pmd_val_set(*pmd, (PxD_FLAG_PRESENT |
+ PxD_FLAG_VALID |
+ PxD_FLAG_ATTACHED)
+ + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
else
#endif
- pmd_val(*pmd) = _PAGE_TABLE + (__u32)__pa((unsigned long)pte);
+ __pmd_val_set(*pmd, (PxD_FLAG_PRESENT | PxD_FLAG_VALID)
+ + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT));
}
#define pmd_populate(mm, pmd, pte_page) \
pmd_populate_kernel(mm, pmd, page_address(pte_page))
-/* NOTE: pte must be in ZONE_DMA (<4GB) so that the pmd pointer
- * can be housed in 32 bits */
static inline struct page *
pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
- struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT|GFP_DMA);
+ struct page *page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
if (likely(page != NULL))
clear_page(page_address(page));
return page;
static inline pte_t *
pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
{
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|GFP_DMA);
+ pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
if (likely(pte != NULL))
clear_page(pte);
return pte;
/* This is the size of the initially mapped kernel memory (i.e. currently
* 0 to 1<<23 == 8MB */
+#ifdef CONFIG_64BIT
+#define KERNEL_INITIAL_ORDER 24
+#else
#define KERNEL_INITIAL_ORDER 23
+#endif
#define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER)
-#ifdef __LP64__
+#ifdef CONFIG_64BIT
#define PT_NLEVELS 3
#define PGD_ORDER 1 /* Number of pages per pgd */
#define PMD_ORDER 1 /* Number of pages per pmd */
#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
#define _PAGE_KERNEL (_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
+/* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds
+ * are page-aligned, we don't care about the PAGE_OFFSET bits, except
+ * for a few meta-information bits, so we shift the address to be
+ * able to effectively address 40-bits of physical address space. */
+#define _PxD_PRESENT_BIT 31
+#define _PxD_ATTACHED_BIT 30
+#define _PxD_VALID_BIT 29
+
+#define PxD_FLAG_PRESENT (1 << xlate_pabit(_PxD_PRESENT_BIT))
+#define PxD_FLAG_ATTACHED (1 << xlate_pabit(_PxD_ATTACHED_BIT))
+#define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT))
+#define PxD_FLAG_MASK (0xf)
+#define PxD_FLAG_SHIFT (4)
+#define PxD_VALUE_SHIFT (8)
+
#ifndef __ASSEMBLY__
#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
#define pte_clear(xp) do { pte_val(*(xp)) = 0; } while (0)
-#ifdef __LP64__
+#define pmd_flag(x) (pmd_val(x) & PxD_FLAG_MASK)
+#define pmd_address(x) ((unsigned long)(pmd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
+#define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK)
+#define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT)
+
+#ifdef CONFIG_64BIT
/* The first entry of the permanent pmd is not there if it contains
* the gateway marker */
-#define pmd_none(x) (!pmd_val(x) || pmd_val(x) == _PAGE_GATEWAY)
-#define pmd_bad(x) ((pmd_val(x) & ~PAGE_MASK) != _PAGE_TABLE && (pmd_val(x) & ~PAGE_MASK) != (_PAGE_TABLE | _PAGE_GATEWAY))
+#define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED)
#else
#define pmd_none(x) (!pmd_val(x))
-#define pmd_bad(x) ((pmd_val(x) & ~PAGE_MASK) != _PAGE_TABLE)
#endif
-#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+#define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID))
+#define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT)
static inline void pmd_clear(pmd_t *pmd) {
-#ifdef __LP64__
- if(pmd_val(*pmd) & _PAGE_GATEWAY)
+#ifdef CONFIG_64BIT
+ if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED)
/* This is the entry pointing to the permanent pmd
* attached to the pgd; cannot clear it */
- pmd_val(*pmd) = _PAGE_GATEWAY;
+ __pmd_val_set(*pmd, PxD_FLAG_ATTACHED);
else
#endif
- pmd_val(*pmd) = 0;
+ __pmd_val_set(*pmd, 0);
}
#if PT_NLEVELS == 3
-#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
+#define pgd_page(pgd) ((unsigned long) __va(pgd_address(pgd)))
/* For 64 bit we have three level tables */
#define pgd_none(x) (!pgd_val(x))
-#ifdef __LP64__
-#define pgd_bad(x) ((pgd_val(x) & ~PAGE_MASK) != _PAGE_TABLE && (pgd_val(x) & ~PAGE_MASK) != (_PAGE_TABLE | _PAGE_GATEWAY))
-#else
-#define pgd_bad(x) ((pgd_val(x) & ~PAGE_MASK) != _PAGE_TABLE)
-#endif
-#define pgd_present(x) (pgd_val(x) & _PAGE_PRESENT)
+#define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID))
+#define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT)
static inline void pgd_clear(pgd_t *pgd) {
-#ifdef __LP64__
- if(pgd_val(*pgd) & _PAGE_GATEWAY)
+#ifdef CONFIG_64BIT
+ if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED)
/* This is the permanent pmd attached to the pgd; cannot
* free it */
return;
#endif
- pgd_val(*pgd) = 0;
+ __pgd_val_set(*pgd, 0);
}
#else
/*
#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
-#ifdef CONFIG_DISCONTIGMEM
-#define pte_page(x) (phys_to_page(pte_val(x)))
-#else
-#define pte_page(x) (mem_map+(pte_val(x) >> PAGE_SHIFT))
-#endif
+#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
-#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_address(pmd)))
-#define __pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define __pmd_page(pmd) ((unsigned long) __va(pmd_address(pmd)))
#define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd))
#define pgd_index(address) ((address) >> PGDIR_SHIFT)
#ifdef CONFIG_SMP
if (!pte_young(*ptep))
return 0;
- return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), ptep);
+ return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), &pte_val(*ptep));
#else
pte_t pte = *ptep;
if (!pte_young(pte))
#ifdef CONFIG_SMP
if (!pte_dirty(*ptep))
return 0;
- return test_and_clear_bit(xlate_pabit(_PAGE_DIRTY_BIT), ptep);
+ return test_and_clear_bit(xlate_pabit(_PAGE_DIRTY_BIT), &pte_val(*ptep));
#else
pte_t pte = *ptep;
if (!pte_dirty(pte))
#endif
}
-#ifdef CONFIG_SMP
extern spinlock_t pa_dbit_lock;
-#else
-static int pa_dbit_lock; /* dummy to keep the compilers happy */
-#endif
static inline pte_t ptep_get_and_clear(pte_t *ptep)
{
static inline void ptep_mkdirty(pte_t *ptep)
{
#ifdef CONFIG_SMP
- set_bit(xlate_pabit(_PAGE_DIRTY_BIT), ptep);
+ set_bit(xlate_pabit(_PAGE_DIRTY_BIT), &pte_val(*ptep));
#else
pte_t old_pte = *ptep;
set_pte(ptep, pte_mkdirty(old_pte));
extern unsigned long cpu_present_mask;
#define smp_processor_id() (current_thread_info()->cpu)
-#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map)
#endif /* CONFIG_SMP */
#define NO_PROC_ID 0xFF /* No processor magic marker */
#define ANY_PROC_ID 0xFF /* Any processor magic marker */
+static inline int __cpu_disable (void) {
+ return 0;
+}
+static inline void __cpu_die (unsigned int cpu) {
+ while(1)
+ ;
+}
+extern int __cpu_up (unsigned int cpu);
#endif /* __ASM_SMP_H */
* the semaphore address has to be 16-byte aligned.
*/
+#ifndef CONFIG_DEBUG_SPINLOCK
+
+#define __SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } }
#undef SPIN_LOCK_UNLOCKED
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { { 1, 1, 1, 1 } }
+#define SPIN_LOCK_UNLOCKED (spinlock_t) __SPIN_LOCK_UNLOCKED
#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
return __ldcw(a) != 0;
}
+#define spin_lock_own(LOCK, LOCATION) ((void)0)
+
+#else /* !(CONFIG_DEBUG_SPINLOCK) */
+
+#define SPINLOCK_MAGIC 0x1D244B3C
+
+#define __SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 }, SPINLOCK_MAGIC, 10, __FILE__ , NULL, 0, -1, NULL, NULL }
+#undef SPIN_LOCK_UNLOCKED
+#define SPIN_LOCK_UNLOCKED (spinlock_t) __SPIN_LOCK_UNLOCKED
+
+#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
+
+#define CHECK_LOCK(x) \
+ do { \
+ if (unlikely((x)->magic != SPINLOCK_MAGIC)) { \
+ printk(KERN_ERR "%s:%d: spin_is_locked" \
+ " on uninitialized spinlock %p.\n", \
+ __FILE__, __LINE__, (x)); \
+ } \
+ } while(0)
+
+#define spin_is_locked(x) \
+ ({ \
+ CHECK_LOCK(x); \
+ volatile unsigned int *a = __ldcw_align(x); \
+ if (unlikely((*a == 0) && (x)->babble)) { \
+ (x)->babble--; \
+ printk("KERN_WARNING \
+ %s:%d: spin_is_locked(%s/%p) already" \
+ " locked by %s:%d in %s at %p(%d)\n", \
+ __FILE__,__LINE__, (x)->module, (x), \
+ (x)->bfile, (x)->bline, (x)->task->comm,\
+ (x)->previous, (x)->oncpu); \
+ } \
+ *a == 0; \
+ })
+
+#define spin_unlock_wait(x) \
+ do { \
+ CHECK_LOCK(x); \
+ volatile unsigned int *a = __ldcw_align(x); \
+ if (unlikely((*a == 0) && (x)->babble)) { \
+ (x)->babble--; \
+ printk("KERN_WARNING \
+ %s:%d: spin_unlock_wait(%s/%p)" \
+ " owned by %s:%d in %s at %p(%d)\n", \
+ __FILE__,__LINE__, (x)->module, (x), \
+ (x)->bfile, (x)->bline, (x)->task->comm,\
+ (x)->previous, (x)->oncpu); \
+ } \
+ barrier(); \
+ } while (*((volatile unsigned char *)(__ldcw_align(x))) == 0)
+
+extern void _dbg_spin_lock(spinlock_t *lock, const char *base_file, int line_no);
+extern void _dbg_spin_unlock(spinlock_t *lock, const char *, int);
+extern int _dbg_spin_trylock(spinlock_t * lock, const char *, int);
+
+#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
+
+#define _raw_spin_unlock(lock) _dbg_spin_unlock(lock, __FILE__, __LINE__)
+#define _raw_spin_lock(lock) _dbg_spin_lock(lock, __FILE__, __LINE__)
+#define _raw_spin_trylock(lock) _dbg_spin_trylock(lock, __FILE__, __LINE__)
+
+/* just in case we need it */
+#define spin_lock_own(LOCK, LOCATION) \
+do { \
+ volatile unsigned int *a = __ldcw_align(LOCK); \
+ if (!((*a == 0) && ((LOCK)->oncpu == smp_processor_id()))) \
+ printk("KERN_WARNING \
+ %s: called on %d from %p but lock %s on %d\n", \
+ LOCATION, smp_processor_id(), \
+ __builtin_return_address(0), \
+ (*a == 0) ? "taken" : "freed", (LOCK)->on_cpu); \
+} while (0)
+
+#endif /* !(CONFIG_DEBUG_SPINLOCK) */
+
/*
* Read-write spinlocks, allowing multiple readers
* but only one writer.
volatile int counter;
} rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { { { 1, 1, 1, 1 } }, 0 }
+#define RW_LOCK_UNLOCKED (rwlock_t) { __SPIN_LOCK_UNLOCKED, 0 }
#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
/* read_lock, read_unlock are pretty straightforward. Of course it somehow
* sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
+#ifdef CONFIG_DEBUG_RWLOCK
+extern void _dbg_read_lock(rwlock_t * rw, const char *bfile, int bline);
+#define _raw_read_lock(rw) _dbg_read_lock(rw, __FILE__, __LINE__)
+#else
static __inline__ void _raw_read_lock(rwlock_t *rw)
{
unsigned long flags;
_raw_spin_unlock(&rw->lock);
local_irq_restore(flags);
}
+#endif /* CONFIG_DEBUG_RWLOCK */
static __inline__ void _raw_read_unlock(rwlock_t *rw)
{
* writers) in interrupt handlers someone fucked up and we'd dead-lock
* sooner or later anyway. prumpf */
+#ifdef CONFIG_DEBUG_RWLOCK
+extern void _dbg_write_lock(rwlock_t * rw, const char *bfile, int bline);
+#define _raw_write_lock(rw) _dbg_write_lock(rw, __FILE__, __LINE__)
+#else
static __inline__ void _raw_write_lock(rwlock_t *rw)
{
retry:
/* got it. now leave without unlocking */
rw->counter = -1; /* remember we are locked */
}
+#endif /* CONFIG_DEBUG_RWLOCK */
/* write_unlock is absolutely trivial - we don't have to wait for anything */
typedef struct {
volatile unsigned int lock[4];
+#ifdef CONFIG_DEBUG_SPINLOCK
+ unsigned long magic;
+ volatile unsigned int babble;
+ const char *module;
+ char *bfile;
+ int bline;
+ int oncpu;
+ void *previous;
+ struct task_struct * task;
+#endif
} spinlock_t;
#define __lock_aligned __attribute__((__section__(".data.lock_aligned")))
struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain;/* execution domain */
- __u32 flags; /* thread_info flags (see TIF_*) */
- __u32 cpu; /* current CPU */
+ unsigned long flags; /* thread_info flags (see TIF_*) */
mm_segment_t addr_limit; /* user-level address space limit */
- struct restart_block restart_block;
+ __u32 cpu; /* current CPU */
__s32 preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
+ struct restart_block restart_block;
};
#define INIT_THREAD_INFO(tsk) \
return sys_close(fd);
}
-static inline int _exit(int exitcode)
+static inline void _exit(int exitcode)
{
- return sys_exit(exitcode);
+ sys_exit(exitcode);
}
static inline pid_t waitpid(pid_t pid, int *wait_stat, int options)
};
struct unwind_frame_info {
- unsigned long sp;
- unsigned long ip;
struct task_struct *t;
/* Eventually we would like to be able to get at any of the registers
available; but for now we only try to get the sp and ip for each
frame */
/* struct pt_regs regs; */
+ unsigned long sp, ip, rp;
unsigned long prev_sp, prev_ip;
};
void * unwind_table_add(const char *name, unsigned long base_addr,
unsigned long gp,
- const void *start, const void *end);
+ void *start, void *end);
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
- struct pt_regs *regs);
+ unsigned long sp, unsigned long ip, unsigned long rp);
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
+void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
int unwind_once(struct unwind_frame_info *info);
int unwind_to_user(struct unwind_frame_info *info);
/* These are the same regardless of whether this is an SMP kernel or not. */
#define flush_cache_mm(__mm) \
do { if ((__mm) == current->mm) flushw_user(); } while(0)
-extern void flush_cache_range(struct vm_area_struct *, unsigned long, unsigned long);
+#define flush_cache_range(vma, start, end) \
+ flush_cache_mm((vma)->vm_mm)
#define flush_cache_page(vma, page) \
flush_cache_mm((vma)->vm_mm)
spin_unlock(&mm->page_table_lock);
}
-extern void __flush_tlb_mm(unsigned long, unsigned long);
-
#define deactivate_mm(tsk,mm) do { } while (0)
/* Activate a new MM instance for the current task. */
#define pmd_populate(MM,PMD,PTE_PAGE) \
pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
-extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
+extern pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address);
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+ pte_t *pte = __pte_alloc_one_kernel(mm, address);
+ if (pte) {
+ struct page *page = virt_to_page(pte);
+ page->mapping = (void *) mm;
+ page->index = address & PMD_MASK;
+ }
+ return pte;
+}
static inline struct page *
pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
- pte_t *pte = pte_alloc_one_kernel(mm, addr);
- if (pte)
- return virt_to_page(pte);
+ pte_t *pte = __pte_alloc_one_kernel(mm, addr);
+ if (pte) {
+ struct page *page = virt_to_page(pte);
+ page->mapping = (void *) mm;
+ page->index = addr & PMD_MASK;
+ return page;
+ }
return NULL;
}
free_page((unsigned long)pte);
}
-#define pte_free_kernel(pte) free_pte_fast(pte)
-#define pte_free(pte) free_pte_fast(page_address(pte))
+static inline void pte_free_kernel(pte_t *pte)
+{
+ virt_to_page(pte)->mapping = NULL;
+ free_pte_fast(pte);
+}
+
+static inline void pte_free(struct page *ptepage)
+{
+ ptepage->mapping = NULL;
+ free_pte_fast(page_address(ptepage));
+}
+
#define pmd_free(pmd) free_pmd_fast(pmd)
#define pgd_free(pgd) free_pgd_fast(pgd)
#define pgd_alloc(mm) get_pgd_fast()
#include <linux/sched.h>
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified. Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
/* Entries per page directory level. */
#define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3))
* is different so we can optimize correctly for 32-bit tasks.
*/
#define REAL_PTRS_PER_PMD (1UL << PMD_BITS)
-#define PTRS_PER_PMD ((const int)(test_thread_flag(TIF_32BIT) ? \
- (1UL << (32 - (PAGE_SHIFT-3) - PAGE_SHIFT)) : \
- (REAL_PTRS_PER_PMD)))
+
+/* This is gross, but unless we do this gcc retests the
+ * thread flag every interation in pmd traversal loops.
+ */
+extern unsigned long __ptrs_per_pmd(void) __attribute_const__;
+#define PTRS_PER_PMD __ptrs_per_pmd()
/*
* We cannot use the top address range because VPTE table lives there. This
((unsigned long) __va((((unsigned long)pgd_val(pgd))<<11UL)))
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
-#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
#define pmd_none(pmd) (!pmd_val(pmd))
#define pmd_bad(pmd) (0)
#define pmd_present(pmd) (pmd_val(pmd) != 0U)
* Undefined behaviour if not..
*/
#define pte_read(pte) (pte_val(pte) & _PAGE_READ)
-#define pte_exec(pte) pte_read(pte)
+#define pte_exec(pte) (pte_val(pte) & _PAGE_EXEC)
#define pte_write(pte) (pte_val(pte) & _PAGE_WRITE)
#define pte_dirty(pte) (pte_val(pte) & _PAGE_MODIFIED)
#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED)
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
+/* Actual page table PTE updates. */
+extern void tlb_batch_add(pte_t *ptep, pte_t orig);
+
+static inline void set_pte(pte_t *ptep, pte_t pte)
+{
+ pte_t orig = *ptep;
+
+ *ptep = pte;
+ if (pte_present(orig))
+ tlb_batch_add(ptep, orig);
+}
+
+#define pte_clear(ptep) set_pte((ptep), __pte(0UL))
+
extern pgd_t swapper_pg_dir[1];
/* These do nothing with the way I have things setup. */
current_thread_info()->kernel_cntd0 += (unsigned int)(__tmp);\
current_thread_info()->kernel_cntd1 += ((__tmp) >> 32); \
} \
+ flush_tlb_pending(); \
save_and_clear_fpu(); \
/* If you are tempted to conditionalize the following */ \
/* so that ASI is only written if it changes, think again. */ \
struct pt_regs *kregs;
struct exec_domain *exec_domain;
int preempt_count;
+ int __pad;
unsigned long *utraps;
#define TI_FPREGS 0x00000500
/* We embed this in the uppermost byte of thread_info->flags */
-#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */
-#define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */
-#define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */
-#define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */
+#define FAULT_CODE_WRITE 0x01 /* Write access, implies D-TLB */
+#define FAULT_CODE_DTLB 0x02 /* Miss happened in D-TLB */
+#define FAULT_CODE_ITLB 0x04 /* Miss happened in I-TLB */
+#define FAULT_CODE_WINFIXUP 0x08 /* Miss happened during spill/fill */
+#define FAULT_CODE_BLKCOMMIT 0x10 /* Use blk-commit ASI in copy_page */
#if PAGE_SHIFT == 13
#define THREAD_SIZE (2*PAGE_SIZE)
#define TIF_NEWSIGNALS 6 /* wants new-style signals */
#define TIF_32BIT 7 /* 32-bit binary */
#define TIF_NEWCHILD 8 /* just-spawned child process */
-
-/* XXX Make this one FAULT_CODE_BLKCOMMIT XXX */
-#define TIF_BLKCOMMIT 9 /* use ASI_BLK_COMMIT_* in copy_user_page */
-
+/* TIF_* value 9 is available */
#define TIF_POLLING_NRFLAG 10
#define TIF_SYSCALL_SUCCESS 11
/* NOTE: Thread flags >= 12 should be ones we have no interest
#define _TIF_NEWSIGNALS (1<<TIF_NEWSIGNALS)
#define _TIF_32BIT (1<<TIF_32BIT)
#define _TIF_NEWCHILD (1<<TIF_NEWCHILD)
-#define _TIF_BLKCOMMIT (1<<TIF_BLKCOMMIT)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_SYSCALL_SUCCESS (1<<TIF_SYSCALL_SUCCESS)
#ifndef _SPARC64_TLB_H
#define _SPARC64_TLB_H
-#define tlb_flush(tlb) \
-do { if ((tlb)->fullmm) \
- flush_tlb_mm((tlb)->mm);\
-} while (0)
+#include <linux/config.h>
+#include <linux/swap.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
-#define tlb_start_vma(tlb, vma) \
-do { if (!(tlb)->fullmm) \
- flush_cache_range(vma, vma->vm_start, vma->vm_end); \
-} while (0)
+#define TLB_BATCH_NR 192
-#define tlb_end_vma(tlb, vma) \
-do { if (!(tlb)->fullmm) \
- flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
-} while (0)
+/*
+ * For UP we don't need to worry about TLB flush
+ * and page free order so much..
+ */
+#ifdef CONFIG_SMP
+ #define FREE_PTE_NR 506
+ #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U)
+#else
+ #define FREE_PTE_NR 1
+ #define tlb_fast_mode(bp) 1
+#endif
-#define __tlb_remove_tlb_entry(tlb, ptep, address) \
- do { } while (0)
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int pages_nr;
+ unsigned int need_flush;
+ unsigned int tlb_frozen;
+ unsigned int tlb_nr;
+ unsigned long freed;
+ unsigned long vaddrs[TLB_BATCH_NR];
+ struct page *pages[FREE_PTE_NR];
+};
-#include <asm-generic/tlb.h>
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-#define __pmd_free_tlb(tlb, pmd) pmd_free(pmd)
-#define __pte_free_tlb(tlb, pte) pte_free(pte)
+#ifdef CONFIG_SMP
+extern void smp_flush_tlb_pending(struct mm_struct *,
+ unsigned long, unsigned long *);
+#endif
+
+extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
+extern void flush_tlb_pending(void);
+
+static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+ struct mmu_gather *mp = &per_cpu(mmu_gathers, smp_processor_id());
+
+ BUG_ON(mp->tlb_nr);
+
+ mp->mm = mm;
+ mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
+ mp->tlb_frozen = full_mm_flush;
+ mp->freed = 0;
+
+ return mp;
+}
+
+
+static inline void tlb_flush_mmu(struct mmu_gather *mp)
+{
+ if (mp->need_flush) {
+ mp->need_flush = 0;
+ if (!tlb_fast_mode(mp)) {
+ free_pages_and_swap_cache(mp->pages, mp->pages_nr);
+ mp->pages_nr = 0;
+ }
+ }
+
+}
+
+#ifdef CONFIG_SMP
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+#define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
+#else
+#define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT)
+#endif
+
+static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
+{
+ unsigned long freed = mp->freed;
+ struct mm_struct *mm = mp->mm;
+ unsigned long rss = mm->rss;
+
+ if (rss < freed)
+ freed = rss;
+ mm->rss = rss - freed;
+
+ tlb_flush_mmu(mp);
+
+ if (mp->tlb_frozen) {
+ unsigned long context = mm->context;
+
+ if (CTX_VALID(context))
+ do_flush_tlb_mm(mm);
+ mp->tlb_frozen = 0;
+ } else
+ flush_tlb_pending();
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+}
+
+static inline unsigned int tlb_is_full_mm(struct mmu_gather *mp)
+{
+ return mp->tlb_frozen;
+}
+
+static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
+{
+ mp->need_flush = 1;
+ if (tlb_fast_mode(mp)) {
+ free_page_and_swap_cache(page);
+ return;
+ }
+ mp->pages[mp->pages_nr++] = page;
+ if (mp->pages_nr >= FREE_PTE_NR)
+ tlb_flush_mmu(mp);
+}
+
+#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
+#define pte_free_tlb(mp,ptepage) pte_free(ptepage)
+#define pmd_free_tlb(mp,pmdp) pmd_free(pmdp)
+
+#define tlb_migrate_finish(mm) do { } while (0)
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
#endif /* _SPARC64_TLB_H */
/* TLB flush operations. */
+extern void flush_tlb_pending(void);
+
+#define flush_tlb_range(vma,start,end) \
+ do { (void)(start); flush_tlb_pending(); } while (0)
+#define flush_tlb_page(vma,addr) flush_tlb_pending()
+#define flush_tlb_mm(mm) flush_tlb_pending()
+
extern void __flush_tlb_all(void);
-extern void __flush_tlb_mm(unsigned long context, unsigned long r);
-extern void __flush_tlb_range(unsigned long context, unsigned long start,
- unsigned long r, unsigned long end,
- unsigned long pgsz, unsigned long size);
extern void __flush_tlb_page(unsigned long context, unsigned long page, unsigned long r);
extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
#define flush_tlb_kernel_range(start,end) \
__flush_tlb_kernel_range(start,end)
-#define flush_tlb_mm(__mm) \
-do { if (CTX_VALID((__mm)->context)) \
- __flush_tlb_mm(CTX_HWBITS((__mm)->context), SECONDARY_CONTEXT); \
-} while (0)
-
-#define flush_tlb_range(__vma, start, end) \
-do { if (CTX_VALID((__vma)->vm_mm->context)) { \
- unsigned long __start = (start)&PAGE_MASK; \
- unsigned long __end = PAGE_ALIGN(end); \
- __flush_tlb_range(CTX_HWBITS((__vma)->vm_mm->context), __start, \
- SECONDARY_CONTEXT, __end, PAGE_SIZE, \
- (__end - __start)); \
- } \
-} while (0)
-
-#define flush_tlb_vpte_range(__mm, start, end) \
-do { if (CTX_VALID((__mm)->context)) { \
- unsigned long __start = (start)&PAGE_MASK; \
- unsigned long __end = PAGE_ALIGN(end); \
- __flush_tlb_range(CTX_HWBITS((__mm)->context), __start, \
- SECONDARY_CONTEXT, __end, PAGE_SIZE, \
- (__end - __start)); \
- } \
-} while (0)
-
-#define flush_tlb_page(vma, page) \
-do { struct mm_struct *__mm = (vma)->vm_mm; \
- if (CTX_VALID(__mm->context)) \
- __flush_tlb_page(CTX_HWBITS(__mm->context), (page)&PAGE_MASK, \
- SECONDARY_CONTEXT); \
-} while (0)
-
-#define flush_tlb_vpte_page(mm, addr) \
-do { struct mm_struct *__mm = (mm); \
- if (CTX_VALID(__mm->context)) \
- __flush_tlb_page(CTX_HWBITS(__mm->context), (addr)&PAGE_MASK, \
- SECONDARY_CONTEXT); \
-} while (0)
-
#else /* CONFIG_SMP */
extern void smp_flush_tlb_all(void);
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
-extern void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
- unsigned long end);
extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
-extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page);
#define flush_tlb_all() smp_flush_tlb_all()
-#define flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
-#define flush_tlb_range(vma, start, end) \
- smp_flush_tlb_range((vma)->vm_mm, start, end)
-#define flush_tlb_vpte_range(mm, start, end) \
- smp_flush_tlb_range(mm, start, end)
#define flush_tlb_kernel_range(start, end) \
smp_flush_tlb_kernel_range(start, end)
-#define flush_tlb_page(vma, page) \
- smp_flush_tlb_page((vma)->vm_mm, page)
-#define flush_tlb_vpte_page(mm, page) \
- smp_flush_tlb_page((mm), page)
#endif /* ! CONFIG_SMP */
-static __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start,
- unsigned long end)
-{
- /* Note the signed type. */
- long s = start, e = end, vpte_base;
- /* Nobody should call us with start below VM hole and end above.
- See if it is really true. */
- BUG_ON(s > e);
-#if 0
- /* Currently free_pgtables guarantees this. */
- s &= PMD_MASK;
- e = (e + PMD_SIZE - 1) & PMD_MASK;
-#endif
- vpte_base = (tlb_type == spitfire ?
- VPTE_BASE_SPITFIRE :
- VPTE_BASE_CHEETAH);
-
- flush_tlb_vpte_range(mm,
- vpte_base + (s >> (PAGE_SHIFT - 3)),
- vpte_base + (e >> (PAGE_SHIFT - 3)));
-}
+extern void flush_tlb_pgtables(struct mm_struct *, unsigned long, unsigned long);
#endif /* _SPARC64_TLBFLUSH_H */
*/
#define CONFIG_MTD_MODULE 1
#undef CONFIG_MTD_DEBUG
-#define CONFIG_MTD_PARTITIONS_MODULE 1
+#define CONFIG_MTD_PARTITIONS 1
#define CONFIG_MTD_CONCAT_MODULE 1
#define CONFIG_MTD_REDBOOT_PARTS_MODULE 1
#undef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
#undef CONFIG_MTD_REDBOOT_PARTS_READONLY
+#define CONFIG_MTD_CMDLINE_PARTS 1
/*
* User Modules And Translation Layers
#define CONFIG_NET_DIVERT 1
#undef CONFIG_ECONET
#define CONFIG_WAN_ROUTER_MODULE 1
-#undef CONFIG_NET_FASTROUTE
#undef CONFIG_NET_HW_FLOWCONTROL
/*
#define CONFIG_BT_HCIBLUECARD_MODULE 1
#define CONFIG_BT_HCIBTUART_MODULE 1
#define CONFIG_BT_HCIVHCI_MODULE 1
-#define CONFIG_TUX_MODULE 1
-
-/*
- * TUX options
- */
-#define CONFIG_TUX_EXTCGI 1
-#undef CONFIG_TUX_EXTENDED_LOG
-#undef CONFIG_TUX_DEBUG
+#undef CONFIG_TUX
#define CONFIG_NETDEVICES 1
#define CONFIG_DUMMY_MODULE 1
#define CONFIG_BONDING_MODULE 1
#define CONFIG_DEBUG_KERNEL 1
#define CONFIG_EARLY_PRINTK 1
#define CONFIG_DEBUG_STACKOVERFLOW 1
-#undef CONFIG_DEBUG_STACK_USAGE
+#define CONFIG_DEBUG_STACK_USAGE 1
#undef CONFIG_DEBUG_SLAB
#define CONFIG_MAGIC_SYSRQ 1
-#undef CONFIG_DEBUG_SPINLOCK
+#define CONFIG_DEBUG_SPINLOCK 1
#undef CONFIG_DEBUG_PAGEALLOC
#undef CONFIG_DEBUG_HIGHMEM
#define CONFIG_DEBUG_INFO 1
#define CONFIG_CRYPTO_CAST6_MODULE 1
#define CONFIG_CRYPTO_TEA_MODULE 1
#define CONFIG_CRYPTO_ARC4_MODULE 1
+#define CONFIG_CRYPTO_KHAZAD_MODULE 1
#define CONFIG_CRYPTO_DEFLATE_MODULE 1
#define CONFIG_CRYPTO_MICHAEL_MIC_MODULE 1
#define CONFIG_CRYPTO_CRC32C_MODULE 1
extern void blk_recount_segments(request_queue_t *, struct bio *);
extern int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
extern int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
-extern int scsi_cmd_ioctl(struct gendisk *, unsigned int, void __user *);
+extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
extern void blk_start_queue(request_queue_t *q);
extern void blk_stop_queue(request_queue_t *q);
extern void __blk_stop_queue(request_queue_t *q);
extern int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip,
struct file *fp);
extern int cdrom_release(struct cdrom_device_info *cdi, struct file *fp);
-extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct inode *ip,
- unsigned int cmd, unsigned long arg);
+extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi,
+ struct inode *ip, unsigned int cmd, unsigned long arg);
extern int cdrom_media_changed(struct cdrom_device_info *);
extern int register_cdrom(struct cdrom_device_info *cdi);
#include <linux/fcntl.h>
-extern long generic_file_fcntl(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp);
-
extern int fcntl_getlk(struct file *, struct flock __user *);
extern int fcntl_setlk(struct file *, unsigned int, struct flock __user *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
- long (*fcntl)(int fd, unsigned int cmd,
- unsigned long arg, struct file *filp);
+ int (*check_flags)(int);
+ int (*dir_notify)(struct file *filp, unsigned long arg);
};
struct inode_operations {
#define DRIVER(drive) ((drive)->driver)
-extern int generic_ide_ioctl(struct block_device *, unsigned, unsigned long);
+extern int generic_ide_ioctl(struct file *, struct block_device *, unsigned, unsigned long);
/*
* ide_hwifs[] is the master data structure used to keep track
struct packet_type;
struct vlan_collection;
struct vlan_dev_info;
+struct hlist_node;
#include <linux/proc_fs.h> /* for proc_dir_entry */
#include <linux/netdevice.h>
struct vlan_group {
int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */
+ struct hlist_node hlist; /* linked list */
struct net_device *vlan_devices[VLAN_GROUP_ARRAY_LEN];
-
- struct vlan_group *next; /* the next in the list */
+ struct rcu_head rcu;
};
struct vlan_priority_tci_mapping {
/*
- * $Id: mtd.h,v 1.54 2004/07/15 01:13:12 dwmw2 Exp $
+ * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $
*
* Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
*
#include <linux/module.h>
#include <linux/uio.h>
+#include <linux/mtd/compatmac.h>
#include <mtd/mtd-abi.h>
#define MTD_CHAR_MAJOR 90
#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
+
+#ifdef CONFIG_MTD_PARTITIONS
+void mtd_erase_callback(struct erase_info *instr);
+#else
+static inline void mtd_erase_callback(struct erase_info *instr)
+{
+ if (instr->callback)
+ instr->callback(instr);
+}
+#endif
+
/*
* Debugging macro and defines
*/
* For boards with physically mapped flash and using
* drivers/mtd/maps/physmap.c mapping driver.
*
- * $Id: physmap.h,v 1.2 2004/07/14 17:48:46 dwmw2 Exp $
+ * $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $
*
* Copyright (C) 2003 MontaVista Software Inc.
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
/*
* Board needs to specify the exact mapping during their setup time.
*/
-static inline void physmap_configure(unsigned long addr, unsigned long size, int buswidth, void (*set_vpp)(struct map_info *, int) )
+static inline void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) )
{
physmap_map.phys = addr;
physmap_map.size = size;
- physmap_map.buswidth = buswidth;
+ physmap_map.bankwidth = bankwidth;
physmap_map.set_vpp = set_vpp;
}
#if defined(CONFIG_PPC32) && defined(CONFIG_6xx)
extern unsigned long powersave_nap;
int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
- void __user *buffer, size_t *lenp);
+ void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
/* Global VLAN variables */
/* Our listing of VLAN group(s) */
-struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE];
-spinlock_t vlan_group_lock = SPIN_LOCK_UNLOCKED;
+struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
#define vlan_grp_hashfn(IDX) ((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK)
static char vlan_fullname[] = "802.1Q VLAN Support";
.func = vlan_skb_recv, /* VLAN receive method */
};
+/* Bits of netdev state that are propogated from real device to virtual */
+#define VLAN_LINK_STATE_MASK \
+ ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER))
+
/* End of global variables definitions. */
/*
* references left.
*/
for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) {
- if (vlan_group_hash[i] != NULL)
- BUG();
+ BUG_ON(!hlist_empty(&vlan_group_hash[i]));
}
vlan_proc_cleanup();
module_init(vlan_proto_init);
module_exit(vlan_cleanup_module);
-/* Must be invoked with vlan_group_lock held. */
+/* Must be invoked with RCU read lock (no preempt) */
static struct vlan_group *__vlan_find_group(int real_dev_ifindex)
{
struct vlan_group *grp;
+ struct hlist_node *n;
+ int hash = vlan_grp_hashfn(real_dev_ifindex);
- for (grp = vlan_group_hash[vlan_grp_hashfn(real_dev_ifindex)];
- grp != NULL;
- grp = grp->next) {
+ hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) {
if (grp->real_dev_ifindex == real_dev_ifindex)
- break;
+ return grp;
}
- return grp;
-}
-
-/* Must hold vlan_group_lock. */
-static void __grp_hash(struct vlan_group *grp)
-{
- struct vlan_group **head;
-
- head = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)];
- grp->next = *head;
- *head = grp;
-}
-
-/* Must hold vlan_group_lock. */
-static void __grp_unhash(struct vlan_group *grp)
-{
- struct vlan_group *next, **pprev;
-
- pprev = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)];
- next = *pprev;
- while (next != grp) {
- pprev = &next->next;
- next = *pprev;
- }
- *pprev = grp->next;
+ return NULL;
}
/* Find the protocol handler. Assumes VID < VLAN_VID_MASK.
*
- * Must be invoked with vlan_group_lock held.
+ * Must be invoked with RCU read lock (no preempt)
*/
struct net_device *__find_vlan_dev(struct net_device *real_dev,
unsigned short VID)
return NULL;
}
+static void vlan_rcu_free(struct rcu_head *rcu)
+{
+ kfree(container_of(rcu, struct vlan_group, rcu));
+}
+
+
/* This returns 0 if everything went fine.
* It will return 1 if the group was killed as a result.
* A negative return indicates failure.
if (vlan_id >= VLAN_VID_MASK)
return -EINVAL;
- spin_lock_bh(&vlan_group_lock);
+ ASSERT_RTNL();
grp = __vlan_find_group(real_dev_ifindex);
- spin_unlock_bh(&vlan_group_lock);
ret = 0;
if (real_dev->features & NETIF_F_HW_VLAN_RX)
real_dev->vlan_rx_register(real_dev, NULL);
- spin_lock_bh(&vlan_group_lock);
- __grp_unhash(grp);
- spin_unlock_bh(&vlan_group_lock);
+ hlist_del_rcu(&grp->hlist);
- /* Free the group, after we have removed it
- * from the hash.
- */
- kfree(grp);
- grp = NULL;
+ /* Free the group, after all cpu's are done. */
+ call_rcu(&grp->rcu, vlan_rcu_free);
+ grp = NULL;
ret = 1;
}
}
new_dev->set_mac_address = vlan_dev_set_mac_address;
new_dev->set_multicast_list = vlan_dev_set_multicast_list;
new_dev->destructor = free_netdev;
+ new_dev->do_ioctl = vlan_dev_ioctl;
}
/* Attach a VLAN device to a mac address (ie Ethernet Card).
struct vlan_group *grp;
struct net_device *new_dev;
struct net_device *real_dev; /* the ethernet device */
- int r;
char name[IFNAMSIZ];
#ifdef VLAN_DEBUG
if (!(real_dev->flags & IFF_UP))
goto out_unlock;
- spin_lock_bh(&vlan_group_lock);
- r = (__find_vlan_dev(real_dev, VLAN_ID) != NULL);
- spin_unlock_bh(&vlan_group_lock);
-
- if (r) {
+ if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) {
/* was already registered. */
printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
goto out_unlock;
new_dev->flags = real_dev->flags;
new_dev->flags &= ~IFF_UP;
+ new_dev->state = real_dev->state & VLAN_LINK_STATE_MASK;
+
/* need 4 bytes for extra VLAN header info,
* hope the underlying device can handle it.
*/
/* So, got the sucker initialized, now lets place
* it into our local structure.
*/
- spin_lock_bh(&vlan_group_lock);
grp = __vlan_find_group(real_dev->ifindex);
- spin_unlock_bh(&vlan_group_lock);
/* Note, we are running under the RTNL semaphore
* so it cannot "appear" on us.
memset(grp, 0, sizeof(struct vlan_group));
grp->real_dev_ifindex = real_dev->ifindex;
- spin_lock_bh(&vlan_group_lock);
- __grp_hash(grp);
- spin_unlock_bh(&vlan_group_lock);
+ hlist_add_head_rcu(&grp->hlist,
+ &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]);
if (real_dev->features & NETIF_F_HW_VLAN_RX)
real_dev->vlan_rx_register(real_dev, grp);
static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
{
- struct net_device *dev = (struct net_device *)(ptr);
- struct vlan_group *grp = NULL;
+ struct net_device *dev = ptr;
+ struct vlan_group *grp = __vlan_find_group(dev->ifindex);
int i, flgs;
- struct net_device *vlandev = NULL;
-
- spin_lock_bh(&vlan_group_lock);
- grp = __vlan_find_group(dev->ifindex);
- spin_unlock_bh(&vlan_group_lock);
+ struct net_device *vlandev;
if (!grp)
goto out;
*/
switch (event) {
- case NETDEV_CHANGEADDR:
- case NETDEV_GOING_DOWN:
- /* Ignore for now */
+ case NETDEV_CHANGE:
+ /* Propogate real device state to vlan devices */
+ flgs = dev->state & VLAN_LINK_STATE_MASK;
+ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+ vlandev = grp->vlan_devices[i];
+ if (!vlandev)
+ continue;
+
+ if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) {
+ vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK)
+ | flgs;
+ netdev_state_change(vlandev);
+ }
+ }
break;
case NETDEV_DOWN:
ret = unregister_vlan_dev(dev,
VLAN_DEV_INFO(vlandev)->vlan_id);
- dev_put(vlandev);
unregister_netdevice(vlandev);
/* Group was destroyed? */
#define VLAN_GRP_HASH_SHIFT 5
#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT)
#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1)
-extern struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE];
-extern spinlock_t vlan_group_lock;
+extern struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
/* Find a VLAN device by the MAC address of its Ethernet device, and
* it's VLAN ID. The default configuration is to have VLAN's scope
* NOT follow the spec for VLANs, but may be useful for doing very
* large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs.
*
- * Must be invoked with vlan_group_lock held and that lock MUST NOT
- * be dropped until a reference is obtained on the returned device.
- * You may drop the lock earlier if you are running under the RTNL
- * semaphore, however.
+ * Must be invoked with rcu_read_lock (ie preempt disabled)
+ * or with RTNL.
*/
struct net_device *__find_vlan_dev(struct net_device* real_dev,
unsigned short VID); /* vlan.c */
int vlan_dev_set_mac_address(struct net_device *dev, void* addr);
int vlan_dev_open(struct net_device* dev);
int vlan_dev_stop(struct net_device* dev);
+int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio);
int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val);
/* We have 12 bits of vlan ID.
*
- * We must not drop the vlan_group_lock until we hold a
+ * We must not drop allow preempt until we hold a
* reference to the device (netif_rx does that) or we
* fail.
*/
- spin_lock_bh(&vlan_group_lock);
+ rcu_read_lock();
skb->dev = __find_vlan_dev(dev, vid);
if (!skb->dev) {
- spin_unlock_bh(&vlan_group_lock);
+ rcu_read_unlock();
#ifdef VLAN_DEBUG
printk(VLAN_DBG "%s: ERROR: No net_device for VID: %i on dev: %s [%i]\n",
*/
if (dev != VLAN_DEV_INFO(skb->dev)->real_dev) {
- spin_unlock_bh(&vlan_group_lock);
+ rcu_read_unlock();
#ifdef VLAN_DEBUG
printk(VLAN_DBG "%s: dropping skb: %p because came in on wrong device, dev: %s real_dev: %s, skb_dev: %s\n",
/* TODO: Add a more specific counter here. */
stats->rx_errors++;
}
- spin_unlock_bh(&vlan_group_lock);
+ rcu_read_lock();
return 0;
}
/* TODO: Add a more specific counter here. */
stats->rx_errors++;
}
- spin_unlock_bh(&vlan_group_lock);
+ rcu_read_unlock();
return 0;
}
/* TODO: Add a more specific counter here. */
stats->rx_errors++;
}
- spin_unlock_bh(&vlan_group_lock);
+ rcu_read_unlock();
return 0;
}
vlan_flush_mc_list(dev);
return 0;
}
+
+int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+ struct ifreq ifrr;
+ int err = -EOPNOTSUPP;
+
+ strncpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
+ ifrr.ifr_ifru = ifr->ifr_ifru;
+
+ switch(cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ if (real_dev->do_ioctl && netif_device_present(real_dev))
+ err = real_dev->do_ioctl(dev, &ifrr, cmd);
+ break;
+
+ case SIOCETHTOOL:
+ err = dev_ethtool(&ifrr);
+ }
+
+ if (!err)
+ ifr->ifr_ifru = ifrr.ifr_ifru;
+
+ return err;
+}
+
/** Taken from Gleb + Lennert's VLAN code, and modified... */
void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
{
If unsure, say N.
-config NET_FASTROUTE
- bool "Fast switching (read help!)"
- depends on EXPERIMENTAL
- ---help---
- Saying Y here enables direct NIC-to-NIC (NIC = Network Interface
- Card) data transfers on the local network, which is fast.
-
- IMPORTANT NOTE: This option is NOT COMPATIBLE with "Network packet
- filtering" (CONFIG_NETFILTER). Say N here if you say Y there.
-
- However, it will work with all options in the "Advanced router"
- section (except for "Use TOS value as routing key" and
- "Use FWMARK value as routing key").
-
- At the moment, few devices support fast switching (tulip is one of
- them, a modified 8390 driver can be found at
- <ftp://ftp.tux.org/pub/net/ip-routing/fastroute/fastroute-8390.tar.gz>).
-
- If unsure, say N.
-
config NET_HW_FLOWCONTROL
bool "Forwarding between high speed interfaces"
depends on EXPERIMENTAL
const struct sk_buff *skb)
{
if (skb->dev == p->dev ||
- skb->len > p->dev->mtu ||
p->state != BR_STATE_FORWARDING)
return 0;
int br_dev_queue_push_xmit(struct sk_buff *skb)
{
+ if (skb->len > skb->dev->mtu)
+ kfree_skb(skb);
+ else {
#ifdef CONFIG_BRIDGE_NETFILTER
- /* ip_refrag calls ip_fragment, which doesn't copy the MAC header. */
- nf_bridge_maybe_copy_header(skb);
+ /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
+ nf_bridge_maybe_copy_header(skb);
#endif
- skb_push(skb, ETH_HLEN);
+ skb_push(skb, ETH_HLEN);
- dev_queue_xmit(skb);
+ dev_queue_xmit(skb);
+ }
return 0;
}
if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
return skb->len;
- read_lock(&qdisc_tree_lock);
+ read_lock_bh(&qdisc_tree_lock);
if (!tcm->tcm_parent)
q = dev->qdisc_sleeping;
else
if (cl)
cops->put(q, cl);
out:
- read_unlock(&qdisc_tree_lock);
+ read_unlock_bh(&qdisc_tree_lock);
dev_put(dev);
return skb->len;
}
#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x30010 /* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */
#if HTB_VER >> 16 != TC_HTB_PROTOVER
#error "Mismatched sch_htb.c and pkt_sch.h"
struct htb_class_inner {
struct rb_root feed[TC_HTB_NUMPRIO]; /* feed trees */
struct rb_node *ptr[TC_HTB_NUMPRIO]; /* current class ptr */
+ /* When class changes from state 1->2 and disconnects from
+ parent's feed then we lost ptr value and start from the
+ first child again. Here we store classid of the
+ last valid ptr (used when ptr is NULL). */
+ u32 last_ptr_id[TC_HTB_NUMPRIO];
} inner;
} un;
struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */
struct rb_root row[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
int row_mask[TC_HTB_MAXDEPTH];
struct rb_node *ptr[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
+ u32 last_ptr_id[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
/* self wait list - roots of wait PQs per row */
struct rb_root wait_pq[TC_HTB_MAXDEPTH];
int prio = ffz(~m);
m &= ~(1 << prio);
- if (p->un.inner.ptr[prio] == cl->node+prio)
- htb_next_rb_node(p->un.inner.ptr + prio);
+ if (p->un.inner.ptr[prio] == cl->node+prio) {
+ /* we are removing child which is pointed to from
+ parent feed - forget the pointer but remember
+ classid */
+ p->un.inner.last_ptr_id[prio] = cl->classid;
+ p->un.inner.ptr[prio] = NULL;
+ }
htb_safe_rb_erase(cl->node + prio,p->un.inner.feed + prio);
return HZ/10;
}
+/* Returns class->node+prio from id-tree where classe's id is >= id. NULL
+ is no such one exists. */
+static struct rb_node *
+htb_id_find_next_upper(int prio,struct rb_node *n,u32 id)
+{
+ struct rb_node *r = NULL;
+ while (n) {
+ struct htb_class *cl = rb_entry(n,struct htb_class,node[prio]);
+ if (id == cl->classid) return n;
+
+ if (id > cl->classid) {
+ n = n->rb_right;
+ } else {
+ r = n;
+ n = n->rb_left;
+ }
+ }
+ return r;
+}
+
/**
* htb_lookup_leaf - returns next leaf class in DRR order
*
* Find leaf where current feed pointers points to.
*/
static struct htb_class *
-htb_lookup_leaf(struct rb_root *tree,int prio,struct rb_node **pptr)
+htb_lookup_leaf(HTB_ARGQ struct rb_root *tree,int prio,struct rb_node **pptr,u32 *pid)
{
int i;
struct {
struct rb_node *root;
struct rb_node **pptr;
+ u32 *pid;
} stk[TC_HTB_MAXDEPTH],*sp = stk;
BUG_TRAP(tree->rb_node);
sp->root = tree->rb_node;
sp->pptr = pptr;
+ sp->pid = pid;
for (i = 0; i < 65535; i++) {
+ HTB_DBG(4,2,"htb_lleaf ptr=%p pid=%X\n",*sp->pptr,*sp->pid);
+
+ if (!*sp->pptr && *sp->pid) {
+ /* ptr was invalidated but id is valid - try to recover
+ the original or next ptr */
+ *sp->pptr = htb_id_find_next_upper(prio,sp->root,*sp->pid);
+ }
+ *sp->pid = 0; /* ptr is valid now so that remove this hint as it
+ can become out of date quickly */
if (!*sp->pptr) { /* we are at right end; rewind & go up */
*sp->pptr = sp->root;
while ((*sp->pptr)->rb_left)
return cl;
(++sp)->root = cl->un.inner.feed[prio].rb_node;
sp->pptr = cl->un.inner.ptr+prio;
+ sp->pid = cl->un.inner.last_ptr_id+prio;
}
}
BUG_TRAP(0);
struct sk_buff *skb = NULL;
struct htb_class *cl,*start;
/* look initial class up in the row */
- start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
+ start = cl = htb_lookup_leaf (HTB_PASSQ q->row[level]+prio,prio,
+ q->ptr[level]+prio,q->last_ptr_id[level]+prio);
do {
next:
if ((q->row_mask[level] & (1 << prio)) == 0)
return NULL;
- next = htb_lookup_leaf (q->row[level]+prio,
- prio,q->ptr[level]+prio);
+ next = htb_lookup_leaf (HTB_PASSQ q->row[level]+prio,
+ prio,q->ptr[level]+prio,q->last_ptr_id[level]+prio);
+
if (cl == start) /* fix start if we just deleted it */
start = next;
cl = next;
}
q->nwc_hit++;
htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
- cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
+ cl = htb_lookup_leaf (HTB_PASSQ q->row[level]+prio,prio,q->ptr[level]+prio,
+ q->last_ptr_id[level]+prio);
+
} while (cl != start);
if (likely(skb != NULL)) {
write_lock_bh(&xfrm_policy_lock);
pol = __xfrm_policy_unlink(pol, dir);
write_unlock_bh(&xfrm_policy_lock);
- if (pol)
+ if (pol) {
+ if (dir < XFRM_POLICY_MAX)
+ atomic_inc(&flow_cache_genid);
xfrm_policy_kill(pol);
+ }
}
int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)