aboutsummaryrefslogtreecommitdiff
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/Kconfig15
-rw-r--r--arch/ia64/Kconfig.debug11
-rw-r--r--arch/ia64/configs/sn2_defconfig7
-rw-r--r--arch/ia64/configs/tiger_defconfig54
-rw-r--r--arch/ia64/configs/zx1_defconfig166
-rw-r--r--arch/ia64/defconfig140
-rw-r--r--arch/ia64/hp/common/sba_iommu.c4
-rw-r--r--arch/ia64/hp/sim/simeth.c6
-rw-r--r--arch/ia64/hp/sim/simserial.c23
-rw-r--r--arch/ia64/ia32/ia32priv.h2
-rw-r--r--arch/ia64/kernel/Makefile2
-rw-r--r--arch/ia64/kernel/acpi.c88
-rw-r--r--arch/ia64/kernel/domain.c78
-rw-r--r--arch/ia64/kernel/entry.S122
-rw-r--r--arch/ia64/kernel/entry.h2
-rw-r--r--arch/ia64/kernel/fsys.S147
-rw-r--r--arch/ia64/kernel/gate.S62
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c3
-rw-r--r--arch/ia64/kernel/iosapic.c147
-rw-r--r--arch/ia64/kernel/irq_ia64.c15
-rw-r--r--arch/ia64/kernel/ivt.S211
-rw-r--r--arch/ia64/kernel/jprobes.S61
-rw-r--r--arch/ia64/kernel/kprobes.c721
-rw-r--r--arch/ia64/kernel/mca.c2
-rw-r--r--arch/ia64/kernel/numa.c57
-rw-r--r--arch/ia64/kernel/perfmon.c1
-rw-r--r--arch/ia64/kernel/process.c24
-rw-r--r--arch/ia64/kernel/ptrace.c37
-rw-r--r--arch/ia64/kernel/setup.c52
-rw-r--r--arch/ia64/kernel/signal.c7
-rw-r--r--arch/ia64/kernel/smp.c5
-rw-r--r--arch/ia64/kernel/smpboot.c45
-rw-r--r--arch/ia64/kernel/topology.c9
-rw-r--r--arch/ia64/kernel/traps.c39
-rw-r--r--arch/ia64/kernel/unwind.c12
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S7
-rw-r--r--arch/ia64/lib/flush.S46
-rw-r--r--arch/ia64/mm/discontig.c441
-rw-r--r--arch/ia64/mm/fault.c8
-rw-r--r--arch/ia64/mm/init.c3
-rw-r--r--arch/ia64/pci/pci.c70
-rw-r--r--arch/ia64/sn/include/pci/pcibr_provider.h151
-rw-r--r--arch/ia64/sn/include/pci/pic.h261
-rw-r--r--arch/ia64/sn/include/pci/tiocp.h256
-rw-r--r--arch/ia64/sn/include/xtalk/hubdev.h2
-rw-r--r--arch/ia64/sn/kernel/io_init.c207
-rw-r--r--arch/ia64/sn/kernel/iomv.c6
-rw-r--r--arch/ia64/sn/kernel/irq.c255
-rw-r--r--arch/ia64/sn/kernel/setup.c56
-rw-r--r--arch/ia64/sn/kernel/sn2/ptc_deadlock.S1
-rw-r--r--arch/ia64/sn/kernel/tiocx.c19
-rw-r--r--arch/ia64/sn/kernel/xpc.h12
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c20
-rw-r--r--arch/ia64/sn/kernel/xpc_main.c18
-rw-r--r--arch/ia64/sn/kernel/xpc_partition.c2
-rw-r--r--arch/ia64/sn/pci/pci_dma.c19
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_ate.c2
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c15
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c58
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_reg.c8
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c15
61 files changed, 2600 insertions, 1735 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 34e603cc171..cbb3e0cef93 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -161,6 +161,8 @@ config IA64_PAGE_SIZE_64KB
endchoice
+source kernel/Kconfig.hz
+
config IA64_BRL_EMU
bool
depends on ITANIUM
@@ -197,7 +199,7 @@ config HOLES_IN_ZONE
bool
default y if VIRTUAL_MEM_MAP
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
bool "Discontiguous memory support"
depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
@@ -218,13 +220,6 @@ config IOSAPIC
depends on !IA64_HP_SIM
default y
-config IA64_SGI_SN_SIM
- bool "SGI Medusa Simulator Support"
- depends on IA64_SGI_SN2
- help
- If you are compiling a kernel that will run under SGI's IA-64
- simulator (Medusa) then say Y, otherwise say N.
-
config IA64_SGI_SN_XP
tristate "Support communication between SGI SSIs"
select IA64_UNCACHED_ALLOCATOR
@@ -300,6 +295,8 @@ config PREEMPT
Say Y here if you are building a kernel for a desktop, embedded
or real-time system. Say N if you are unsure.
+source "mm/Kconfig"
+
config HAVE_DEC_LOCK
bool
depends on (SMP || PREEMPT)
@@ -419,6 +416,8 @@ endmenu
endif
+source "net/Kconfig"
+
source "drivers/Kconfig"
source "fs/Kconfig"
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index de9d507ba0f..fda67ac993d 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,6 +2,17 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
+config KPROBES
+ bool "Kprobes"
+ depends on DEBUG_KERNEL
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+
+
choice
prompt "Physical memory granularity"
default IA64_GRANULE_64MB
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index a01bb02d074..04d0b00a2b8 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -78,10 +78,9 @@ CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y
CONFIG_VIRTUAL_MEM_MAP=y
CONFIG_HOLES_IN_ZONE=y
-CONFIG_DISCONTIGMEM=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
# CONFIG_IA64_CYCLONE is not set
CONFIG_IOSAPIC=y
-CONFIG_IA64_SGI_SN_SIM=y
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=512
@@ -99,7 +98,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y
# Firmware Drivers
#
CONFIG_EFI_VARS=y
-# CONFIG_EFI_PCDP is not set
+CONFIG_EFI_PCDP=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -650,7 +649,7 @@ CONFIG_MMTIMER=y
#
# Console display driver support
#
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
#
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 9086b789f6a..73454eee26f 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc3
-# Tue May 3 15:55:04 2005
+# Linux kernel version: 2.6.13-rc1-20050629
+# Wed Jun 29 15:28:12 2005
#
#
@@ -67,6 +67,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_IA64_HP_ZX1 is not set
@@ -79,18 +80,29 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_NUMA is not set
CONFIG_VIRTUAL_MEM_MAP=y
CONFIG_HOLES_IN_ZONE=y
CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=4
CONFIG_HOTPLUG_CPU=y
# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
@@ -256,6 +268,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -285,6 +298,7 @@ CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -313,11 +327,8 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -366,8 +377,10 @@ CONFIG_DM_ZERO=m
# Fusion MPT device support
#
CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_CTL is not set
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=y
#
# IEEE 1394 (FireWire) support
@@ -394,6 +407,7 @@ CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -406,6 +420,8 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_TUNNEL is not set
CONFIG_IP_TCPDIAG=y
# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
@@ -506,9 +522,11 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
@@ -595,10 +613,7 @@ CONFIG_GAMEPORT=m
# CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461X is not set
-CONFIG_SOUND_GAMEPORT=m
#
# Character devices
@@ -611,7 +626,6 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_CYCLADES is not set
# CONFIG_MOXA_SMARTIO is not set
# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
# CONFIG_SPECIALIX is not set
@@ -628,7 +642,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -742,6 +755,7 @@ CONFIG_USB_DEVICEFS=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=m
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -778,9 +792,11 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -837,7 +853,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_TEST is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -856,12 +872,17 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_INFINIBAND is not set
#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
@@ -921,7 +942,6 @@ CONFIG_NTFS_FS=m
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_TMPFS_XATTR=y
@@ -952,15 +972,18 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
CONFIG_NFS_DIRECTIO=y
CONFIG_NFSD=m
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1068,6 +1091,7 @@ CONFIG_LOG_BUF_SHIFT=20
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
# CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1089,7 +1113,7 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 21d6f9bab5e..b7755e4436d 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Wed Dec 29 09:05:48 2004
+# Linux kernel version: 2.6.13-rc1-20050629
+# Wed Jun 29 15:31:11 2005
#
#
@@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS 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_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -59,12 +63,15 @@ CONFIG_IA64=y
CONFIG_64BIT=y
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_IA64_GENERIC is not set
# CONFIG_IA64_DIG is not set
CONFIG_IA64_HP_ZX1=y
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
# CONFIG_IA64_SGI_SN2 is not set
# CONFIG_IA64_HP_SIM is not set
# CONFIG_ITANIUM is not set
@@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
CONFIG_IA64_L1_CACHE_SHIFT=7
# CONFIG_NUMA is not set
CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
# CONFIG_IA64_CYCLONE is not set
CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=16
# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
CONFIG_COMPAT=y
CONFIG_IA64_MCA_RECOVERY=y
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
#
# Firmware Drivers
@@ -120,6 +141,7 @@ CONFIG_ACPI_BUS=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
#
# Bus options (PCI, PCMCIA)
@@ -129,6 +151,7 @@ CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
#
# PCI Hotplug Support
@@ -138,7 +161,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
#
@@ -147,10 +169,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# Device Drivers
#
@@ -184,6 +202,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
@@ -203,6 +222,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -246,6 +266,7 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -275,6 +296,7 @@ CONFIG_CHR_DEV_OSST=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -288,6 +310,7 @@ CONFIG_SCSI_LOGGING=y
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
@@ -303,13 +326,10 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -319,8 +339,6 @@ 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_SCSI_QLOGIC_FC is not set
CONFIG_SCSI_QLOGIC_1280=y
@@ -331,7 +349,7 @@ CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -344,9 +362,9 @@ CONFIG_SCSI_QLA2XXX=y
#
# Fusion MPT device support
#
-CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
@@ -368,12 +386,12 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -386,6 +404,8 @@ CONFIG_IP_MULTICAST=y
# CONFIG_INET_TUNNEL is not set
# CONFIG_IP_TCPDIAG is not set
# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
@@ -405,8 +425,6 @@ CONFIG_NETFILTER=y
CONFIG_IP_NF_ARPTABLES=y
# CONFIG_IP_NF_ARPFILTER is not set
# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
#
# SCTP Configuration (EXPERIMENTAL)
@@ -483,7 +501,6 @@ CONFIG_NET_PCI=y
# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -505,9 +522,11 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
@@ -565,18 +584,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
@@ -586,6 +593,16 @@ CONFIG_SERIO=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -603,7 +620,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
#
@@ -611,6 +627,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -644,6 +661,12 @@ CONFIG_DRM_RADEON=y
# CONFIG_DRM_SIS is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
#
# I2C support
@@ -668,6 +691,7 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_ISA is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
@@ -691,10 +715,14 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
@@ -705,21 +733,29 @@ CONFIG_I2C_ALGOPCF=y
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
#
# Other I2C Chip support
#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -746,6 +782,7 @@ CONFIG_VIDEO_DEV=y
#
# Video Adapters
#
+# CONFIG_TUNER_MULTI_I2C is not set
# CONFIG_VIDEO_BT848 is not set
# CONFIG_VIDEO_CPIA is not set
# CONFIG_VIDEO_SAA5246A is not set
@@ -778,6 +815,11 @@ CONFIG_VIDEO_DEV=y
# Graphics support
#
CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
@@ -785,6 +827,7 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON_OLD is not set
@@ -801,6 +844,7 @@ CONFIG_FB_RADEON_DEBUG=y
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -820,6 +864,7 @@ CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -869,6 +914,8 @@ CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
@@ -876,6 +923,7 @@ CONFIG_SND_AC97_CODEC=y
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_ALS4000 is not set
@@ -893,13 +941,14 @@ CONFIG_SND_FM801_TEA575X=y
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
#
# Open Sound System
@@ -909,6 +958,8 @@ CONFIG_SND_FM801_TEA575X=y
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -920,8 +971,6 @@ CONFIG_USB_BANDWIDTH=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@@ -929,7 +978,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
@@ -947,12 +999,11 @@ CONFIG_USB_UHCI_HCD=y
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -966,9 +1017,11 @@ CONFIG_USB_HIDINPUT=y
CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
@@ -978,7 +1031,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
#
# USB Multimedia devices
@@ -992,6 +1044,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_SE401 is not set
# CONFIG_USB_SN9C102 is not set
# CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
#
# USB Network Adapters
@@ -1001,6 +1054,7 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
#
# USB port drivers
@@ -1016,7 +1070,6 @@ CONFIG_USB_HIDDEV=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -1025,9 +1078,11 @@ CONFIG_USB_HIDDEV=y
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
#
-# USB ATM/DSL drivers
+# USB DSL modem support
#
#
@@ -1041,12 +1096,22 @@ CONFIG_USB_HIDDEV=y
# CONFIG_MMC is not set
#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
# File systems
#
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
# CONFIG_EXT2_FS_POSIX_ACL is not set
# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1056,6 +1121,10 @@ CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -1089,7 +1158,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
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_TMPFS_XATTR=y
@@ -1120,15 +1188,18 @@ CONFIG_RAMFS=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
# CONFIG_NFSD_V4 is not set
# CONFIG_NFSD_TCP is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
CONFIG_RPCSEC_GSS_KRB5=y
@@ -1209,6 +1280,8 @@ CONFIG_NLS_UTF8=y
# CONFIG_CRC_CCITT is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
#
# Profiling support
@@ -1218,14 +1291,18 @@ CONFIG_CRC32=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_KPROBES=y
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
CONFIG_IA64_PRINT_HAZARDS=y
@@ -1252,6 +1329,7 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 9997ef45ab2..8444add7638 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Thu Jan 6 11:13:13 2005
+# Linux kernel version: 2.6.12
+# Tue Jun 21 11:30:42 2005
#
#
@@ -10,6 +10,7 @@
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
@@ -21,24 +22,27 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=20
CONFIG_HOTPLUG=y
CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
#
# Loadable module support
@@ -63,9 +67,11 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_IA64_GENERIC=y
# CONFIG_IA64_DIG is not set
# CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
# CONFIG_IA64_SGI_SN2 is not set
# CONFIG_IA64_HP_SIM is not set
# CONFIG_ITANIUM is not set
@@ -77,13 +83,15 @@ CONFIG_IA64_PAGE_SIZE_16KB=y
CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y
CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_DISCONTIGMEM=y
+CONFIG_HOLES_IN_ZONE=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_IA64_CYCLONE=y
CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_SMP=y
CONFIG_NR_CPUS=512
CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
# CONFIG_PREEMPT is not set
CONFIG_HAVE_DEC_LOCK=y
CONFIG_IA32_SUPPORT=y
@@ -135,6 +143,7 @@ CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
#
# PCI Hotplug Support
@@ -144,7 +153,6 @@ CONFIG_HOTPLUG_PCI=m
CONFIG_HOTPLUG_PCI_ACPI=m
# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
# CONFIG_HOTPLUG_PCI_SHPC is not set
#
@@ -153,10 +161,6 @@ CONFIG_HOTPLUG_PCI_ACPI=m
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# Device Drivers
#
@@ -190,6 +194,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
@@ -209,6 +214,7 @@ CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
#
# ATA/ATAPI/MFM/RLL support
@@ -283,6 +289,7 @@ CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -310,13 +317,21 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+CONFIG_SCSI_SATA_VITESSE=y
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
@@ -326,7 +341,6 @@ 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_QLOGIC_ISP is not set
CONFIG_SCSI_QLOGIC_FC=y
# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
CONFIG_SCSI_QLOGIC_1280=y
@@ -337,6 +351,7 @@ CONFIG_SCSI_QLA22XX=m
CONFIG_SCSI_QLA2300=m
CONFIG_SCSI_QLA2322=m
# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -359,12 +374,16 @@ CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_EMC is not set
#
# Fusion MPT device support
#
CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_MAX_SGE=128
# CONFIG_FUSION_CTL is not set
#
@@ -387,7 +406,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
@@ -447,7 +465,6 @@ CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
#
# ARCnet devices
@@ -484,9 +501,7 @@ CONFIG_NET_PCI=y
# CONFIG_FORCEDETH is not set
# CONFIG_DGRS is not set
CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
CONFIG_E100=m
-# CONFIG_E100_NAPI is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
@@ -508,9 +523,11 @@ CONFIG_E1000=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
@@ -568,25 +585,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-CONFIG_GAMEPORT=m
-CONFIG_SOUND_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -604,6 +602,23 @@ CONFIG_MOUSE_PS2=y
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461X is not set
+
+#
# Character devices
#
CONFIG_VT=y
@@ -613,11 +628,15 @@ CONFIG_SERIAL_NONSTANDARD=y
# CONFIG_ROCKETPORT is not set
# CONFIG_CYCLADES is not set
# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_SYNCLINK is not set
+# CONFIG_ISI is not set
# CONFIG_SYNCLINKMP is not set
# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
# CONFIG_STALDRV is not set
CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SGI_MBCS=m
#
# Serial drivers
@@ -639,6 +658,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_SGI_L1_CONSOLE=y
CONFIG_SERIAL_SGI_IOC4=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -664,6 +684,7 @@ CONFIG_EFI_RTC=y
CONFIG_AGP=m
CONFIG_AGP_I460=m
CONFIG_AGP_HP_ZX1=m
+CONFIG_AGP_SGI_TIOCA=m
CONFIG_DRM=m
CONFIG_DRM_TDFX=m
CONFIG_DRM_R128=m
@@ -675,9 +696,15 @@ CONFIG_HPET=y
# CONFIG_HPET_RTC_IRQ is not set
CONFIG_HPET_MMAP=y
CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
CONFIG_MMTIMER=y
#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
# I2C support
#
# CONFIG_I2C is not set
@@ -761,6 +788,8 @@ CONFIG_SND_CS46XX=m
CONFIG_SND_CS46XX_NEW_DSP=y
CONFIG_SND_CS4281=m
CONFIG_SND_EMU10K1=m
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
@@ -785,13 +814,14 @@ CONFIG_SND_FM801=m
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
#
# Open Sound System
@@ -801,6 +831,8 @@ CONFIG_SND_FM801=m
#
# USB support
#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB=m
# CONFIG_USB_DEBUG is not set
@@ -812,8 +844,6 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
# CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
#
# USB Host Controller Drivers
@@ -822,6 +852,8 @@ CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_SPLIT_ISO is not set
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_SL811_HCD is not set
@@ -839,12 +871,11 @@ CONFIG_USB_UHCI_HCD=m
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -894,6 +925,7 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=m
#
# USB port drivers
@@ -909,7 +941,6 @@ CONFIG_USB_HIDINPUT=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
@@ -918,6 +949,8 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_TEST is not set
#
@@ -970,7 +1003,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
CONFIG_REISERFS_FS_SECURITY=y
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
# CONFIG_XFS_RT is not set
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
@@ -1048,7 +1086,7 @@ CONFIG_NFSD_V4=y
CONFIG_NFSD_TCP=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
CONFIG_RPCSEC_GSS_KRB5=m
@@ -1134,6 +1172,8 @@ CONFIG_NLS_UTF8=m
# CONFIG_CRC_CCITT is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
#
# HP Simulator drivers
@@ -1150,14 +1190,17 @@ CONFIG_CRC32=y
#
# Kernel hacking
#
+# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=20
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
CONFIG_IA64_GRANULE_16MB=y
# CONFIG_IA64_GRANULE_64MB is not set
# CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1184,6 +1227,7 @@ CONFIG_CRYPTO_MD5=m
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
CONFIG_CRYPTO_DES=m
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index b8db6e3e5e8..11957598a8b 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -156,10 +156,13 @@
*/
#define DELAYED_RESOURCE_CNT 64
+#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec
+
#define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
#define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
#define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
#define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
+#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
#define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
@@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = {
{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
{ ZX2_IOC_ID, "zx2", NULL },
{ SX1000_IOC_ID, "sx1000", NULL },
+ { SX2000_IOC_ID, "sx2000", NULL },
};
static struct ioc * __init
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index ae84a1018a8..0639ec0ed01 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -191,7 +191,7 @@ simeth_probe1(void)
unsigned char mac_addr[ETH_ALEN];
struct simeth_local *local;
struct net_device *dev;
- int fd, i, err;
+ int fd, i, err, rc;
/*
* XXX Fix me
@@ -228,7 +228,9 @@ simeth_probe1(void)
return err;
}
- dev->irq = assign_irq_vector(AUTO_ASSIGN);
+ if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ dev->irq = rc;
/*
* attach the interrupt in the simulator, this does enable interrupts
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 786e70718ce..7dcb8582ae0 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/serialP.h>
+#include <linux/sysrq.h>
#include <asm/irq.h>
#include <asm/hw_irq.h>
@@ -149,12 +150,17 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
seen_esc = 2;
continue;
} else if ( seen_esc == 2 ) {
- if ( ch == 'P' ) show_state(); /* F1 key */
-#ifdef CONFIG_KDB
- if ( ch == 'S' )
- kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs);
+ if ( ch == 'P' ) /* F1 */
+ show_state();
+#ifdef CONFIG_MAGIC_SYSRQ
+ if ( ch == 'S' ) { /* F4 */
+ do
+ ch = ia64_ssc(0, 0, 0, 0,
+ SSC_GETCHAR);
+ while (!ch);
+ handle_sysrq(ch, regs, NULL);
+ }
#endif
-
seen_esc = 0;
continue;
}
@@ -976,7 +982,7 @@ static struct tty_operations hp_ops = {
static int __init
simrs_init (void)
{
- int i;
+ int i, rc;
struct serial_state *state;
if (!ia64_platform_is("hpsim"))
@@ -1011,7 +1017,10 @@ simrs_init (void)
if (state->type == PORT_UNKNOWN) continue;
if (!state->irq) {
- state->irq = assign_irq_vector(AUTO_ASSIGN);
+ if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
+ panic("%s: out of interrupt vectors!\n",
+ __FUNCTION__);
+ state->irq = rc;
ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
}
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
index b2de948bdae..e3e9290e3ff 100644
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -241,7 +241,7 @@ typedef struct compat_siginfo {
/* POSIX.1b timers */
struct {
- timer_t _tid; /* timer id */
+ compat_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
char _pad[sizeof(unsigned int) - sizeof(int)];
compat_sigval_t _sigval; /* same as below */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 4c73d8ba2e3..e1fb68ddec2 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -17,9 +17,11 @@ obj-$(CONFIG_IA64_PALINFO) += palinfo.o
obj-$(CONFIG_IOSAPIC) += iosapic.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_SMP) += smp.o smpboot.o domain.o
+obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_PERFMON) += perfmon_default_smpl.o
obj-$(CONFIG_IA64_CYCLONE) += cyclone.o
obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
+obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 72dfd9e7de0..9609f243e5d 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -11,6 +11,7 @@
* Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
* Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
* Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
+ * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
@@ -67,6 +68,11 @@ EXPORT_SYMBOL(pm_power_off);
unsigned char acpi_kbd_controller_present = 1;
unsigned char acpi_legacy_devices;
+static unsigned int __initdata acpi_madt_rev;
+
+unsigned int acpi_cpei_override;
+unsigned int acpi_cpei_phys_cpuid;
+
#define MAX_SAPICS 256
u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
{ [0 ... MAX_SAPICS - 1] = -1 };
@@ -236,9 +242,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end)
if (BAD_MADT_ENTRY(iosapic, end))
return -EINVAL;
- iosapic_init(iosapic->address, iosapic->global_irq_base);
-
- return 0;
+ return iosapic_init(iosapic->address, iosapic->global_irq_base);
}
@@ -267,10 +271,56 @@ acpi_parse_plat_int_src (
(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
platform_intr_list[plintsrc->type] = vector;
+ if (acpi_madt_rev > 1) {
+ acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag;
+ }
+
+ /*
+ * Save the physical id, so we can check when its being removed
+ */
+ acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff;
+
return 0;
}
+unsigned int can_cpei_retarget(void)
+{
+ extern int cpe_vector;
+
+ /*
+ * Only if CPEI is supported and the override flag
+ * is present, otherwise return that its re-targettable
+ * if we are in polling mode.
+ */
+ if (cpe_vector > 0 && !acpi_cpei_override)
+ return 0;
+ else
+ return 1;
+}
+
+unsigned int is_cpu_cpei_target(unsigned int cpu)
+{
+ unsigned int logical_id;
+
+ logical_id = cpu_logical_id(acpi_cpei_phys_cpuid);
+
+ if (logical_id == cpu)
+ return 1;
+ else
+ return 0;
+}
+
+void set_cpei_target_cpu(unsigned int cpu)
+{
+ acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
+}
+
+unsigned int get_cpei_target_cpu(void)
+{
+ return acpi_cpei_phys_cpuid;
+}
+
static int __init
acpi_parse_int_src_ovr (
acpi_table_entry_header *header, const unsigned long end)
@@ -328,6 +378,8 @@ acpi_parse_madt (unsigned long phys_addr, unsigned long size)
acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
+ acpi_madt_rev = acpi_madt->header.revision;
+
/* remember the value for reference after free_initmem() */
#ifdef CONFIG_ITANIUM
has_8259 = 1; /* Firmware on old Itanium systems is broken */
@@ -642,9 +694,11 @@ acpi_boot_init (void)
if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
}
- build_cpu_to_node_map();
# endif
#endif
+#ifdef CONFIG_ACPI_NUMA
+ build_cpu_to_node_map();
+#endif
/* Make boot-up look pretty */
printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
return 0;
@@ -772,7 +826,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
#ifdef CONFIG_ACPI_NUMA
-acpi_status __init
+acpi_status __devinit
acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
{
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -825,4 +879,28 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
return AE_OK;
}
#endif /* CONFIG_NUMA */
+
+int
+acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+ int err;
+
+ if ((err = iosapic_init(phys_addr, gsi_base)))
+ return err;
+
+#if CONFIG_ACPI_NUMA
+ acpi_map_iosapic(handle, 0, NULL, NULL);
+#endif /* CONFIG_ACPI_NUMA */
+
+ return 0;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
+{
+ return iosapic_remove(gsi_base);
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
#endif /* CONFIG_ACPI_BOOT */
diff --git a/arch/ia64/kernel/domain.c b/arch/ia64/kernel/domain.c
index fe532c97043..d65e87b6394 100644
--- a/arch/ia64/kernel/domain.c
+++ b/arch/ia64/kernel/domain.c
@@ -14,7 +14,7 @@
#include <linux/topology.h>
#include <linux/nodemask.h>
-#define SD_NODES_PER_DOMAIN 6
+#define SD_NODES_PER_DOMAIN 16
#ifdef CONFIG_NUMA
/**
@@ -27,7 +27,7 @@
*
* Should use nodemask_t.
*/
-static int __devinit find_next_best_node(int node, unsigned long *used_nodes)
+static int find_next_best_node(int node, unsigned long *used_nodes)
{
int i, n, val, min_val, best_node = 0;
@@ -66,7 +66,7 @@ static int __devinit find_next_best_node(int node, unsigned long *used_nodes)
* should be one that prevents unnecessary balancing, but also spreads tasks
* out optimally.
*/
-static cpumask_t __devinit sched_domain_node_span(int node)
+static cpumask_t sched_domain_node_span(int node)
{
int i;
cpumask_t span, nodemask;
@@ -96,7 +96,7 @@ static cpumask_t __devinit sched_domain_node_span(int node)
#ifdef CONFIG_SCHED_SMT
static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
static struct sched_group sched_group_cpus[NR_CPUS];
-static int __devinit cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu)
{
return cpu;
}
@@ -104,7 +104,7 @@ static int __devinit cpu_to_cpu_group(int cpu)
static DEFINE_PER_CPU(struct sched_domain, phys_domains);
static struct sched_group sched_group_phys[NR_CPUS];
-static int __devinit cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu)
{
#ifdef CONFIG_SCHED_SMT
return first_cpu(cpu_sibling_map[cpu]);
@@ -125,44 +125,36 @@ static struct sched_group *sched_group_nodes[MAX_NUMNODES];
static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
static struct sched_group sched_group_allnodes[MAX_NUMNODES];
-static int __devinit cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu)
{
return cpu_to_node(cpu);
}
#endif
/*
- * Set up scheduler domains and groups. Callers must hold the hotplug lock.
+ * Build sched domains for a given set of cpus and attach the sched domains
+ * to the individual cpus
*/
-void __devinit arch_init_sched_domains(void)
+void build_sched_domains(const cpumask_t *cpu_map)
{
int i;
- cpumask_t cpu_default_map;
/*
- * Setup mask for cpus without special case scheduling requirements.
- * For now this just excludes isolated cpus, but could be used to
- * exclude other special cases in the future.
+ * Set up domains for cpus specified by the cpu_map.
*/
- cpus_complement(cpu_default_map, cpu_isolated_map);
- cpus_and(cpu_default_map, cpu_default_map, cpu_online_map);
-
- /*
- * Set up domains. Isolated domains just stay on the dummy domain.
- */
- for_each_cpu_mask(i, cpu_default_map) {
+ for_each_cpu_mask(i, *cpu_map) {
int group;
struct sched_domain *sd = NULL, *p;
cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
- cpus_and(nodemask, nodemask, cpu_default_map);
+ cpus_and(nodemask, nodemask, *cpu_map);
#ifdef CONFIG_NUMA
if (num_online_cpus()
> SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
sd = &per_cpu(allnodes_domains, i);
*sd = SD_ALLNODES_INIT;
- sd->span = cpu_default_map;
+ sd->span = *cpu_map;
group = cpu_to_allnodes_group(i);
sd->groups = &sched_group_allnodes[group];
p = sd;
@@ -173,7 +165,7 @@ void __devinit arch_init_sched_domains(void)
*sd = SD_NODE_INIT;
sd->span = sched_domain_node_span(cpu_to_node(i));
sd->parent = p;
- cpus_and(sd->span, sd->span, cpu_default_map);
+ cpus_and(sd->span, sd->span, *cpu_map);
#endif
p = sd;
@@ -190,7 +182,7 @@ void __devinit arch_init_sched_domains(void)
group = cpu_to_cpu_group(i);
*sd = SD_SIBLING_INIT;
sd->span = cpu_sibling_map[i];
- cpus_and(sd->span, sd->span, cpu_default_map);
+ cpus_and(sd->span, sd->span, *cpu_map);
sd->parent = p;
sd->groups = &sched_group_cpus[group];
#endif
@@ -198,9 +190,9 @@ void __devinit arch_init_sched_domains(void)
#ifdef CONFIG_SCHED_SMT
/* Set up CPU (sibling) groups */
- for_each_cpu_mask(i, cpu_default_map) {
+ for_each_cpu_mask(i, *cpu_map) {
cpumask_t this_sibling_map = cpu_sibling_map[i];
- cpus_and(this_sibling_map, this_sibling_map, cpu_default_map);
+ cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
if (i != first_cpu(this_sibling_map))
continue;
@@ -213,7 +205,7 @@ void __devinit arch_init_sched_domains(void)
for (i = 0; i < MAX_NUMNODES; i++) {
cpumask_t nodemask = node_to_cpumask(i);
- cpus_and(nodemask, nodemask, cpu_default_map);
+ cpus_and(nodemask, nodemask, *cpu_map);
if (cpus_empty(nodemask))
continue;
@@ -222,7 +214,7 @@ void __devinit arch_init_sched_domains(void)
}
#ifdef CONFIG_NUMA
- init_sched_build_groups(sched_group_allnodes, cpu_default_map,
+ init_sched_build_groups(sched_group_allnodes, *cpu_map,
&cpu_to_allnodes_group);
for (i = 0; i < MAX_NUMNODES; i++) {
@@ -233,12 +225,12 @@ void __devinit arch_init_sched_domains(void)
cpumask_t covered = CPU_MASK_NONE;
int j;
- cpus_and(nodemask, nodemask, cpu_default_map);
+ cpus_and(nodemask, nodemask, *cpu_map);
if (cpus_empty(nodemask))
continue;
domainspan = sched_domain_node_span(i);
- cpus_and(domainspan, domainspan, cpu_default_map);
+ cpus_and(domainspan, domainspan, *cpu_map);
sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL);
sched_group_nodes[i] = sg;
@@ -266,7 +258,7 @@ void __devinit arch_init_sched_domains(void)
int n = (i + j) % MAX_NUMNODES;
cpus_complement(notcovered, covered);
- cpus_and(tmp, notcovered, cpu_default_map);
+ cpus_and(tmp, notcovered, *cpu_map);
cpus_and(tmp, tmp, domainspan);
if (cpus_empty(tmp))
break;
@@ -293,7 +285,7 @@ void __devinit arch_init_sched_domains(void)
#endif
/* Calculate CPU power for physical packages and nodes */
- for_each_cpu_mask(i, cpu_default_map) {
+ for_each_cpu_mask(i, *cpu_map) {
int power;
struct sched_domain *sd;
#ifdef CONFIG_SCHED_SMT
@@ -359,13 +351,35 @@ next_sg:
cpu_attach_domain(sd, i);
}
}
+/*
+ * Set up scheduler domains and groups. Callers must hold the hotplug lock.
+ */
+void arch_init_sched_domains(const cpumask_t *cpu_map)
+{
+ cpumask_t cpu_default_map;
+
+ /*
+ * Setup mask for cpus without special case scheduling requirements.
+ * For now this just excludes isolated cpus, but could be used to
+ * exclude other special cases in the future.
+ */
+ cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
+
+ build_sched_domains(&cpu_default_map);
+}
-void __devinit arch_destroy_sched_domains(void)
+void arch_destroy_sched_domains(const cpumask_t *cpu_map)
{
#ifdef CONFIG_NUMA
int i;
for (i = 0; i < MAX_NUMNODES; i++) {
+ cpumask_t nodemask = node_to_cpumask(i);
struct sched_group *oldsg, *sg = sched_group_nodes[i];
+
+ cpus_and(nodemask, nodemask, *cpu_map);
+ if (cpus_empty(nodemask))
+ continue;
+
if (sg == NULL)
continue;
sg = sg->next;
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index b1d5d3d5276..9be53e1ea40 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -470,18 +470,6 @@ ENTRY(load_switch_stack)
br.cond.sptk.many b7
END(load_switch_stack)
-GLOBAL_ENTRY(__ia64_syscall)
- .regstk 6,0,0,0
- mov r15=in5 // put syscall number in place
- break __BREAK_SYSCALL
- movl r2=errno
- cmp.eq p6,p7=-1,r10
- ;;
-(p6) st4 [r2]=r8
-(p6) mov r8=-1
- br.ret.sptk.many rp
-END(__ia64_syscall)
-
GLOBAL_ENTRY(execve)
mov r15=__NR_execve // put syscall number in place
break __BREAK_SYSCALL
@@ -637,7 +625,7 @@ END(ia64_ret_from_syscall)
* r8-r11: restored (syscall return value(s))
* r12: restored (user-level stack pointer)
* r13: restored (user-level thread pointer)
- * r14: cleared
+ * r14: set to __kernel_syscall_via_epc
* r15: restored (syscall #)
* r16-r17: cleared
* r18: user-level b6
@@ -658,7 +646,7 @@ END(ia64_ret_from_syscall)
* pr: restored (user-level pr)
* b0: restored (user-level rp)
* b6: restored
- * b7: cleared
+ * b7: set to __kernel_syscall_via_epc
* ar.unat: restored (user-level ar.unat)
* ar.pfs: restored (user-level ar.pfs)
* ar.rsc: restored (user-level ar.rsc)
@@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall)
;;
(p6) ld4 r31=[r18] // load current_thread_info()->flags
ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs"
- mov b7=r0 // clear b7
+ nop.i 0
;;
- ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage)
+ mov r16=ar.bsp // M2 get existing backing store pointer
ld8 r18=[r2],PT(R9)-PT(B6) // load b6
(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE?
;;
- mov r16=ar.bsp // M2 get existing backing store pointer
+ ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage)
(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending?
(p6) br.cond.spnt .work_pending_syscall
;;
// start restoring the state saved on the kernel stack (struct pt_regs):
ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
ld8 r11=[r3],PT(CR_IIP)-PT(R11)
- mov f6=f0 // clear f6
+(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE!
;;
invala // M0|1 invalidate ALAT
- rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection
- mov f9=f0 // clear f9
+ rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection
+ cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs
- ld8 r29=[r2],16 // load cr.ipsr
- ld8 r28=[r3],16 // load cr.iip
- mov f8=f0 // clear f8
+ ld8 r29=[r2],16 // M0|1 load cr.ipsr
+ ld8 r28=[r3],16 // M0|1 load cr.iip
+ mov r22=r0 // A clear r22
;;
ld8 r30=[r2],16 // M0|1 load cr.ifs
ld8 r25=[r3],16 // M0|1 load ar.unat
- cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
;;
ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs
-(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
- mov f10=f0 // clear f10
+(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled
+ nop 0
;;
- ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
- ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc
- mov f11=f0 // clear f11
+ ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+ ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc
+ mov f6=f0 // F clear f6
;;
- ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage)
- ld8 r31=[r3],PT(R1)-PT(PR) // load predicates
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+ ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage)
+ ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates
+ mov f7=f0 // F clear f7
;;
- ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr
- ld8.fill r1=[r3],16 // load r1
-(pUStk) mov r17=1
+ ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr
+ ld8.fill r1=[r3],16 // M0|1 load r1
+(pUStk) mov r17=1 // A
;;
- srlz.d // M0 ensure interruption collection is off
- ld8.fill r13=[r3],16
- mov f7=f0 // clear f7
+(pUStk) st1 [r14]=r17 // M2|3
+ ld8.fill r13=[r3],16 // M0|1
+ mov f8=f0 // F clear f8
;;
- ld8.fill r12=[r2] // restore r12 (sp)
- mov.m ar.ssd=r0 // M2 clear ar.ssd
- mov r22=r0 // clear r22
+ ld8.fill r12=[r2] // M0|1 restore r12 (sp)
+ ld8.fill r15=[r3] // M0|1 restore r15
+ mov b6=r18 // I0 restore b6
+
+ addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+ mov f9=f0 // F clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch // B
- ld8.fill r15=[r3] // restore r15
-(pUStk) st1 [r14]=r17
- addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
+ srlz.d // M0 ensure interruption collection is off (for cover)
+ shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
+ cover // B add current frame into dirty partition & set cr.ifs
;;
-(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8
- mov.m ar.csd=r0 // M2 clear ar.csd
- mov b6=r18 // I0 restore b6
+(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8
+ mov r19=ar.bsp // M2 get new backing store pointer
+ mov f10=f0 // F clear f10
+
+ nop.m 0
+ movl r14=__kernel_syscall_via_epc // X
;;
- mov r14=r0 // clear r14
- shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition
-(pKStk) br.cond.dpnt.many skip_rbs_switch
+ mov.m ar.csd=r0 // M2 clear ar.csd
+ mov.m ar.ccv=r0 // M2 clear ar.ccv
+ mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc)
- mov.m ar.ccv=r0 // clear ar.ccv
-(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
- br.cond.sptk.many rbs_switch
+ mov.m ar.ssd=r0 // M2 clear ar.ssd
+ mov f11=f0 // F clear f11
+ br.cond.sptk.many rbs_switch // B
END(ia64_leave_syscall)
#ifdef CONFIG_IA32_SUPPORT
@@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
ldf.fill f7=[r2],PT(F11)-PT(F7)
ldf.fill f8=[r3],32
;;
- srlz.i // ensure interruption collection is off
+ srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned)
mov ar.ccv=r15
;;
ldf.fill f11=[r2]
@@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel)
* NOTE: alloc, loadrs, and cover can't be predicated.
*/
(pNonSys) br.cond.dpnt dont_preserve_current_frame
-
-rbs_switch:
cover // add current frame into dirty partition and set cr.ifs
;;
mov r19=ar.bsp // get new backing store pointer
+rbs_switch:
sub r16=r16,r18 // krbs = old bsp - size of dirty partition
cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs
;;
@@ -1024,14 +1018,14 @@ rse_clear_invalid:
mov loc5=0
mov loc6=0
mov loc7=0
-(pRecurse) br.call.sptk.few b0=rse_clear_invalid
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
;;
mov loc8=0
mov loc9=0
cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret
mov loc10=0
mov loc11=0
-(pReturn) br.ret.sptk.many b0
+(pReturn) br.ret.dptk.many b0
#endif /* !CONFIG_ITANIUM */
# undef pRecurse
# undef pReturn
@@ -1255,7 +1249,7 @@ ENTRY(sys_rt_sigreturn)
stf.spill [r17]=f11
adds out0=16,sp // out0 = &sigscratch
br.call.sptk.many rp=ia64_rt_sigreturn
-.ret19: .restore sp 0
+.ret19: .restore sp,0
adds sp=16,sp
;;
ld8 r9=[sp] // load new ar.unat
@@ -1577,11 +1571,11 @@ sys_call_table:
data8 sys_add_key
data8 sys_request_key
data8 sys_keyctl
+ data8 sys_ioprio_set
+ data8 sys_ioprio_get // 1275
data8 sys_ni_syscall
- data8 sys_ni_syscall // 1275
- data8 sys_set_zone_reclaim
- data8 sys_ni_syscall
- data8 sys_ni_syscall
- data8 sys_ni_syscall
+ data8 sys_inotify_init
+ data8 sys_inotify_add_watch
+ data8 sys_inotify_rm_watch
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
index 6d4ecec989b..78eeb079341 100644
--- a/arch/ia64/kernel/entry.h
+++ b/arch/ia64/kernel/entry.h
@@ -60,7 +60,7 @@
.spillsp @priunat,SW(AR_UNAT)+16+(off); \
.spillsp ar.rnat,SW(AR_RNAT)+16+(off); \
.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off); \
- .spillsp pr,SW(PR)+16+(off))
+ .spillsp pr,SW(PR)+16+(off)
#define DO_SAVE_SWITCH_STACK \
movl r28=1f; \
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index 962b6c4e32b..7d7684a369d 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -531,93 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down)
.altrp b6
.body
/*
- * We get here for syscalls that don't have a lightweight handler. For those, we
- * need to bubble down into the kernel and that requires setting up a minimal
- * pt_regs structure, and initializing the CPU state more or less as if an
- * interruption had occurred. To make syscall-restarts work, we setup pt_regs
- * such that cr_iip points to the second instruction in syscall_via_break.
- * Decrementing the IP hence will restart the syscall via break and not
- * decrementing IP will return us to the caller, as usual. Note that we preserve
- * the value of psr.pp rather than initializing it from dcr.pp. This makes it
- * possible to distinguish fsyscall execution from other privileged execution.
+ * We get here for syscalls that don't have a lightweight
+ * handler. For those, we need to bubble down into the kernel
+ * and that requires setting up a minimal pt_regs structure,
+ * and initializing the CPU state more or less as if an
+ * interruption had occurred. To make syscall-restarts work,
+ * we setup pt_regs such that cr_iip points to the second
+ * instruction in syscall_via_break. Decrementing the IP
+ * hence will restart the syscall via break and not
+ * decrementing IP will return us to the caller, as usual.
+ * Note that we preserve the value of psr.pp rather than
+ * initializing it from dcr.pp. This makes it possible to
+ * distinguish fsyscall execution from other privileged
+ * execution.
*
* On entry:
- * - normal fsyscall handler register usage, except that we also have:
+ * - normal fsyscall handler register usage, except
+ * that we also have:
* - r18: address of syscall entry point
* - r21: ar.fpsr
* - r26: ar.pfs
* - r27: ar.rsc
* - r29: psr
+ *
+ * We used to clear some PSR bits here but that requires slow
+ * serialization. Fortuntely, that isn't really necessary.
+ * The rationale is as follows: we used to clear bits
+ * ~PSR_PRESERVED_BITS in PSR.L. Since
+ * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we
+ * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}.
+ * However,
+ *
+ * PSR.BE : already is turned off in __kernel_syscall_via_epc()
+ * PSR.AC : don't care (kernel normally turns PSR.AC on)
+ * PSR.I : already turned off by the time fsys_bubble_down gets
+ * invoked
+ * PSR.DFL: always 0 (kernel never turns it on)
+ * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
+ * initiative
+ * PSR.DI : always 0 (kernel never turns it on)
+ * PSR.SI : always 0 (kernel never turns it on)
+ * PSR.DB : don't care --- kernel never enables kernel-level
+ * breakpoints
+ * PSR.TB : must be 0 already; if it wasn't zero on entry to
+ * __kernel_syscall_via_epc, the branch to fsys_bubble_down
+ * will trigger a taken branch; the taken-trap-handler then
+ * converts the syscall into a break-based system-call.
*/
-# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \
- | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \
- | IA64_PSR_IC)
/*
- * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have
- * to synthesize.
+ * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.
+ * The rest we have to synthesize.
*/
-# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
+# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \
+ | (0x1 << IA64_PSR_RI_BIT) \
| IA64_PSR_BN | IA64_PSR_I)
- invala
- movl r8=PSR_ONE_BITS
+ invala // M0|1
+ movl r14=ia64_ret_from_syscall // X
- mov r25=ar.unat // save ar.unat (5 cyc)
- movl r9=PSR_PRESERVED_BITS
+ nop.m 0
+ movl r28=__kernel_syscall_via_break // X create cr.iip
+ ;;
- mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0
- movl r28=__kernel_syscall_via_break
+ mov r2=r16 // A get task addr to addl-addressable register
+ adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A
+ mov r31=pr // I0 save pr (2 cyc)
;;
- mov r23=ar.bspstore // save ar.bspstore (12 cyc)
- mov r31=pr // save pr (2 cyc)
- mov r20=r1 // save caller's gp in r20
+ st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
+ addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS
+ add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A
;;
- mov r2=r16 // copy current task addr to addl-addressable register
- and r9=r9,r29
- mov r19=b6 // save b6 (2 cyc)
+ ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags
+ lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store
+ nop.i 0
;;
- mov psr.l=r9 // slam the door (17 cyc to srlz.i)
- or r29=r8,r29 // construct cr.ipsr value to save
- addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS
+ mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0
+ nop.m 0
+ nop.i 0
;;
- // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks
- // we may be reading ar.itc after writing to psr.l. Avoid that message with
- // this directive:
- dv_serialize_data
- mov.m r24=ar.rnat // read ar.rnat (5 cyc lat)
- lfetch.fault.excl.nt1 [r22]
- adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
-
- // ensure previous insn group is issued before we stall for srlz.i:
+ mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore
+ mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!)
+ nop.i 0
;;
- srlz.i // ensure new psr.l has been established
- /////////////////////////////////////////////////////////////////////////////
- ////////// from this point on, execution is not interruptible anymore
- /////////////////////////////////////////////////////////////////////////////
- addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack
- cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1
+ mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS
+ movl r8=PSR_ONE_BITS // X
;;
- st1 [r16]=r0 // clear current->thread.on_ustack flag
- mov ar.bspstore=r22 // switch to kernel RBS
- mov b6=r18 // copy syscall entry-point to b6 (7 cyc)
- add r3=TI_FLAGS+IA64_TASK_SIZE,r2
+ mov r25=ar.unat // M2 (5 cyc) save ar.unat
+ mov r19=b6 // I0 save b6 (2 cyc)
+ mov r20=r1 // A save caller's gp in r20
;;
- ld4 r3=[r3] // r2 = current_thread_info()->flags
- mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc)
- mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0
- br.call.sptk.many b7=ia64_syscall_setup
- ;;
- ssm psr.i
- movl r2=ia64_ret_from_syscall
+ or r29=r8,r29 // A construct cr.ipsr value to save
+ mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc)
+ addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack
+
+ mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc)
+ cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1
+ br.call.sptk.many b7=ia64_syscall_setup // B
;;
- mov rp=r2 // set the real return addr
- and r3=_TIF_SYSCALL_TRACEAUDIT,r3
+ mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
+ mov rp=r14 // I0 set the real return addr
+ and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A
;;
- cmp.eq p8,p0=r3,r0
+ ssm psr.i // M2 we're on kernel stacks now, reenable irqs
+ cmp.eq p8,p0=r3,r0 // A
+(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
-(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8
-(p8) br.call.sptk.many b6=b6 // ignore this return addr
- br.cond.sptk ia64_trace_syscall
+ nop.m 0
+(p8) br.call.sptk.many b6=b6 // B (ignore return address)
+ br.cond.spnt ia64_trace_syscall // B
END(fsys_bubble_down)
.rodata
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index facf75acdc8..86948ce63e4 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
* bundle get executed. The remaining code must be safe even if
* they do not get executed.
*/
- adds r17=-1024,r15
- mov r10=0 // default to successful syscall execution
- epc
+ adds r17=-1024,r15 // A
+ mov r10=0 // A default to successful syscall execution
+ epc // B causes split-issue
}
;;
- rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be"
- LOAD_FSYSCALL_TABLE(r14)
-
- mov r16=IA64_KR(CURRENT) // 12 cycle read latency
- tnat.nz p10,p9=r15
- mov r19=NR_syscalls-1
+ rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
+ LOAD_FSYSCALL_TABLE(r14) // X
;;
- shladd r18=r17,3,r14
-
- srlz.d
- cmp.ne p8,p0=r0,r0 // p8 <- FALSE
- /* Note: if r17 is a NaT, p6 will be set to zero. */
- cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)?
- ;;
-(p6) ld8 r18=[r18]
- mov r21=ar.fpsr
- add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
- ;;
-(p6) mov b7=r18
-(p6) tbit.z p8,p0=r18,0
-(p8) br.dptk.many b7
-
-(p6) rsm psr.i
- mov r27=ar.rsc
- mov r26=ar.pfs
+ mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
+ shladd r18=r17,3,r14 // A
+ mov r19=NR_syscalls-1 // A
+ ;;
+ lfetch [r18] // M0|1
+ mov r29=psr // M2 (12 cyc)
+ // If r17 is a NaT, p6 will be zero
+ cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+ ;;
+ mov r21=ar.fpsr // M2 (12 cyc)
+ tnat.nz p10,p9=r15 // I0
+ mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
+ ;;
+ srlz.d // M0 (forces split-issue) ensure PSR.BE==0
+(p6) ld8 r18=[r18] // M0|1
+ nop.i 0
+ ;;
+ nop.m 0
+(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
+ nop.i 0
;;
- mov r29=psr // read psr (12 cyc load latency)
+(p8) ssm psr.i
+(p6) mov b7=r18 // I0
+(p8) br.dptk.many b7 // B
+
+ mov r27=ar.rsc // M2 (12 cyc)
/*
* brl.cond doesn't work as intended because the linker would convert this branch
* into a branch to a PLT. Perhaps there will be a way to avoid this with some
@@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
* instead.
*/
#ifdef CONFIG_ITANIUM
+(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
+ ;;
(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
;;
(p6) mov b7=r14
@@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
#else
BRL_COND_FSYS_BUBBLE_DOWN(p6)
#endif
-
+ ssm psr.i
mov r10=-1
(p10) mov r8=EINVAL
(p9) mov r8=ENOSYS
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 7bbf019c986..01572814abe 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__strnlen_user);
-#include <asm/unistd.h>
-EXPORT_SYMBOL(__ia64_syscall);
-
/* from arch/ia64/lib */
extern void __divsi3(void);
extern void __udivsi3(void);
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 88b014381df..7936b62f7a2 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -129,14 +129,13 @@ static struct iosapic {
char __iomem *addr; /* base address of IOSAPIC */
unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */
unsigned short num_rte; /* number of RTE in this IOSAPIC */
+ int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
#ifdef CONFIG_NUMA
unsigned short node; /* numa node association via pxm */
#endif
} iosapic_lists[NR_IOSAPICS];
-static int num_iosapic;
-
-static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */
+static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */
static int iosapic_kmalloc_ok;
static LIST_HEAD(free_rte_list);
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
{
int i;
- for (i = 0; i < num_iosapic; i++) {
+ for (i = 0; i < NR_IOSAPICS; i++) {
if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
return i;
}
@@ -490,8 +489,6 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po
}
}
}
- if (vector < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
return vector;
}
@@ -507,6 +504,8 @@ iosapic_reassign_vector (int vector)
if (!list_empty(&iosapic_intr_info[vector].rtes)) {
new_vector = assign_irq_vector(AUTO_ASSIGN);
+ if (new_vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
sizeof(struct iosapic_intr_info));
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
rte->refcnt++;
list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
iosapic_intr_info[vector].count++;
+ iosapic_lists[index].rtes_inuse++;
}
else if (vector_is_shared(vector)) {
struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -734,9 +734,12 @@ again:
spin_unlock_irqrestore(&iosapic_lock, flags);
/* If vector is running out, we try to find a sharable vector */
- vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
- if (vector < 0)
+ vector = assign_irq_vector(AUTO_ASSIGN);
+ if (vector < 0) {
vector = iosapic_find_sharable_vector(trigger, polarity);
+ if (vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ }
spin_lock_irqsave(&irq_descp(vector)->lock, flags);
spin_lock(&iosapic_lock);
@@ -778,7 +781,7 @@ void
iosapic_unregister_intr (unsigned int gsi)
{
unsigned long flags;
- int irq, vector;
+ int irq, vector, index;
irq_desc_t *idesc;
u32 low32;
unsigned long trigger, polarity;
@@ -819,6 +822,9 @@ iosapic_unregister_intr (unsigned int gsi)
list_del(&rte->rte_list);
iosapic_intr_info[vector].count--;
iosapic_free_rte(rte);
+ index = find_iosapic(gsi);
+ iosapic_lists[index].rtes_inuse--;
+ WARN_ON(iosapic_lists[index].rtes_inuse < 0);
trigger = iosapic_intr_info[vector].trigger;
polarity = iosapic_intr_info[vector].polarity;
@@ -881,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
break;
case ACPI_INTERRUPT_INIT:
vector = assign_irq_vector(AUTO_ASSIGN);
+ if (vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
delivery = IOSAPIC_INIT;
break;
case ACPI_INTERRUPT_CPEI:
@@ -952,30 +960,86 @@ iosapic_system_init (int system_pcat_compat)
}
}
-void __init
+static inline int
+iosapic_alloc (void)
+{
+ int index;
+
+ for (index = 0; index < NR_IOSAPICS; index++)
+ if (!iosapic_lists[index].addr)
+ return index;
+
+ printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
+ return -1;
+}
+
+static inline void
+iosapic_free (int index)
+{
+ memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
+}
+
+static inline int
+iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
+{
+ int index;
+ unsigned int gsi_end, base, end;
+
+ /* check gsi range */
+ gsi_end = gsi_base + ((ver >> 16) & 0xff);
+ for (index = 0; index < NR_IOSAPICS; index++) {
+ if (!iosapic_lists[index].addr)
+ continue;
+
+ base = iosapic_lists[index].gsi_base;
+ end = base + iosapic_lists[index].num_rte - 1;
+
+ if (gsi_base < base && gsi_end < base)
+ continue;/* OK */
+
+ if (gsi_base > end && gsi_end > end)
+ continue; /* OK */
+
+ return -EBUSY;
+ }
+ return 0;
+}
+
+int __devinit
iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
{
- int num_rte;
+ int num_rte, err, index;
unsigned int isa_irq, ver;
char __iomem *addr;
+ unsigned long flags;
- addr = ioremap(phys_addr, 0);
- ver = iosapic_version(addr);
+ spin_lock_irqsave(&iosapic_lock, flags);
+ {
+ addr = ioremap(phys_addr, 0);
+ ver = iosapic_version(addr);
- /*
- * The MAX_REDIR register holds the highest input pin
- * number (starting from 0).
- * We add 1 so that we can use it for number of pins (= RTEs)
- */
- num_rte = ((ver >> 16) & 0xff) + 1;
+ if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
+ iounmap(addr);
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+ return err;
+ }
+
+ /*
+ * The MAX_REDIR register holds the highest input pin
+ * number (starting from 0).
+ * We add 1 so that we can use it for number of pins (= RTEs)
+ */
+ num_rte = ((ver >> 16) & 0xff) + 1;
- iosapic_lists[num_iosapic].addr = addr;
- iosapic_lists[num_iosapic].gsi_base = gsi_base;
- iosapic_lists[num_iosapic].num_rte = num_rte;
+ index = iosapic_alloc();
+ iosapic_lists[index].addr = addr;
+ iosapic_lists[index].gsi_base = gsi_base;
+ iosapic_lists[index].num_rte = num_rte;
#ifdef CONFIG_NUMA
- iosapic_lists[num_iosapic].node = MAX_NUMNODES;
+ iosapic_lists[index].node = MAX_NUMNODES;
#endif
- num_iosapic++;
+ }
+ spin_unlock_irqrestore(&iosapic_lock, flags);
if ((gsi_base == 0) && pcat_compat) {
/*
@@ -986,10 +1050,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
for (isa_irq = 0; isa_irq < 16; ++isa_irq)
iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
}
+ return 0;
+}
+
+#ifdef CONFIG_HOTPLUG
+int
+iosapic_remove (unsigned int gsi_base)
+{
+ int index, err = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iosapic_lock, flags);
+ {
+ index = find_iosapic(gsi_base);
+ if (index < 0) {
+ printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
+ __FUNCTION__, gsi_base);
+ goto out;
+ }
+
+ if (iosapic_lists[index].rtes_inuse) {
+ err = -EBUSY;
+ printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
+ __FUNCTION__, gsi_base);
+ goto out;
+ }
+
+ iounmap(iosapic_lists[index].addr);
+ iosapic_free(index);
+ }
+ out:
+ spin_unlock_irqrestore(&iosapic_lock, flags);
+ return err;
}
+#endif /* CONFIG_HOTPLUG */
#ifdef CONFIG_NUMA
-void __init
+void __devinit
map_iosapic_to_node(unsigned int gsi_base, int node)
{
int index;
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 4fe60c7a2e9..6c4d59fd036 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
int
-assign_irq_vector_nopanic (int irq)
+assign_irq_vector (int irq)
{
int pos, vector;
again:
pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
vector = IA64_FIRST_DEVICE_VECTOR + pos;
if (vector > IA64_LAST_DEVICE_VECTOR)
- return -1;
+ return -ENOSPC;
if (test_and_set_bit(pos, ia64_vector_mask))
goto again;
return vector;
}
-int
-assign_irq_vector (int irq)
-{
- int vector = assign_irq_vector_nopanic(irq);
-
- if (vector < 0)
- panic("assign_irq_vector: out of interrupt vectors!");
-
- return vector;
-}
-
void
free_irq_vector (int vector)
{
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index d9c05d53435..3bb3a13c404 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -1,7 +1,7 @@
/*
* arch/ia64/kernel/ivt.S
*
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
* Stephane Eranian <eranian@hpl.hp.com>
* David Mosberger <davidm@hpl.hp.com>
* Copyright (C) 2000, 2002-2003 Intel Co
@@ -405,17 +405,22 @@ ENTRY(nested_dtlb_miss)
* r30: continuation address
* r31: saved pr
*
- * Clobbered: b0, r18, r19, r21, psr.dt (cleared)
+ * Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared)
*/
rsm psr.dt // switch to using physical data addressing
mov r19=IA64_KR(PT_BASE) // get the page table base address
shl r21=r16,3 // shift bit 60 into sign bit
+ mov r18=cr.itir
;;
shr.u r17=r16,61 // get the region number into r17
+ extr.u r18=r18,2,6 // get the faulting page size
;;
cmp.eq p6,p7=5,r17 // is faulting address in region 5?
- shr.u r18=r16,PGDIR_SHIFT // get bits 33-63 of faulting address
+ add r22=-PAGE_SHIFT,r18 // adjustment for hugetlb address
+ add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
;;
+ shr.u r22=r16,r22
+ shr.u r18=r16,r18
(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place
srlz.d
@@ -428,7 +433,7 @@ ENTRY(nested_dtlb_miss)
(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=PTA + IFA(33,42)*8
(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
cmp.eq p7,p6=0,r21 // unused address bits all zeroes?
- shr.u r18=r16,PMD_SHIFT // shift L2 index into position
+ shr.u r18=r22,PMD_SHIFT // shift L2 index into position
;;
ld8 r17=[r17] // fetch the L1 entry (may be 0)
;;
@@ -436,7 +441,7 @@ ENTRY(nested_dtlb_miss)
dep r17=r18,r17,3,(PAGE_SHIFT-3) // compute address of L2 page table entry
;;
(p7) ld8 r17=[r17] // fetch the L2 entry (may be 0)
- shr.u r19=r16,PAGE_SHIFT // shift L3 index into position
+ shr.u r19=r22,PAGE_SHIFT // shift L3 index into position
;;
(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was L2 entry NULL?
dep r17=r19,r17,3,(PAGE_SHIFT-3) // compute address of L3 page table entry
@@ -687,82 +692,118 @@ ENTRY(break_fault)
* to prevent leaking bits from kernel to user level.
*/
DBG_FAULT(11)
- mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat.
- mov r17=cr.iim
- mov r18=__IA64_BREAK_SYSCALL
- mov r21=ar.fpsr
- mov r29=cr.ipsr
- mov r19=b6
- mov r25=ar.unat
- mov r27=ar.rsc
- mov r26=ar.pfs
- mov r28=cr.iip
- mov r31=pr // prepare to save predicates
- mov r20=r1
- ;;
+ mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc)
+ mov r29=cr.ipsr // M2 (12 cyc)
+ mov r31=pr // I0 (2 cyc)
+
+ mov r17=cr.iim // M2 (2 cyc)
+ mov.m r27=ar.rsc // M2 (12 cyc)
+ mov r18=__IA64_BREAK_SYSCALL // A
+
+ mov.m ar.rsc=0 // M2
+ mov.m r21=ar.fpsr // M2 (12 cyc)
+ mov r19=b6 // I0 (2 cyc)
+ ;;
+ mov.m r23=ar.bspstore // M2 (12 cyc)
+ mov.m r24=ar.rnat // M2 (5 cyc)
+ mov.i r26=ar.pfs // I0 (2 cyc)
+
+ invala // M0|1
+ nop.m 0 // M
+ mov r20=r1 // A save r1
+
+ nop.m 0
+ movl r30=sys_call_table // X
+
+ mov r28=cr.iip // M2 (2 cyc)
+ cmp.eq p0,p7=r18,r17 // I0 is this a system call?
+(p7) br.cond.spnt non_syscall // B no ->
+ //
+ // From this point on, we are definitely on the syscall-path
+ // and we can use (non-banked) scratch registers.
+ //
+///////////////////////////////////////////////////////////////////////
+ mov r1=r16 // A move task-pointer to "addl"-addressable reg
+ mov r2=r16 // A setup r2 for ia64_syscall_setup
+ add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = &current_thread_info()->flags
+
adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
- cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so)
-(p7) br.cond.spnt non_syscall
+ adds r15=-1024,r15 // A subtract 1024 from syscall number
+ mov r3=NR_syscalls - 1
;;
- ld1 r17=[r16] // load current->thread.on_ustack flag
- st1 [r16]=r0 // clear current->thread.on_ustack flag
- add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT
+ ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag
+ ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags
+ extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr
+
+ shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024)
+ addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS
+ cmp.leu p6,p7=r15,r3 // A syscall number in range?
;;
- invala
- /* adjust return address so we skip over the break instruction: */
+ lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS
+(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point
+ tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT?
- extr.u r8=r29,41,2 // extract ei field from cr.ipsr
- ;;
- cmp.eq p6,p7=2,r8 // isr.ei==2?
- mov r2=r1 // setup r2 for ia64_syscall_setup
- ;;
-(p6) mov r8=0 // clear ei to 0
-(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped
-(p7) adds r8=1,r8 // increment ei to next slot
- ;;
- cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already?
- dep r29=r8,r29,41,2 // insert new ei into cr.ipsr
+ mov.m ar.bspstore=r22 // M2 switch to kernel RBS
+ cmp.eq p8,p9=2,r8 // A isr.ei==2?
;;
- // switch from user to kernel RBS:
- MINSTATE_START_SAVE_MIN_VIRT
- br.call.sptk.many b7=ia64_syscall_setup
- ;;
- MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1
- ssm psr.ic | PSR_DEFAULT_BITS
- ;;
- srlz.i // guarantee that interruption collection is on
- mov r3=NR_syscalls - 1
- ;;
-(p15) ssm psr.i // restore psr.i
- // p10==true means out registers are more than 8 or r15's Nat is true
-(p10) br.cond.spnt.many ia64_ret_from_syscall
- ;;
- movl r16=sys_call_table
+(p8) mov r8=0 // A clear ei to 0
+(p7) movl r30=sys_ni_syscall // X
- adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
- movl r2=ia64_ret_from_syscall
- ;;
- shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024)
- cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ?
- mov rp=r2 // set the real return addr
+(p8) adds r28=16,r28 // A switch cr.iip to next bundle
+(p9) adds r8=1,r8 // A increment ei to next slot
+ nop.i 0
;;
-(p6) ld8 r20=[r20] // load address of syscall entry point
-(p7) movl r20=sys_ni_syscall
- add r2=TI_FLAGS+IA64_TASK_SIZE,r13
- ;;
- ld4 r2=[r2] // r2 = current_thread_info()->flags
- ;;
- and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit
+ mov.m r25=ar.unat // M2 (5 cyc)
+ dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr
+ adds r15=1024,r15 // A restore original syscall number
+ //
+ // If any of the above loads miss in L1D, we'll stall here until
+ // the data arrives.
+ //
+///////////////////////////////////////////////////////////////////////
+ st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
+ mov b6=r30 // I0 setup syscall handler branch reg early
+ cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already?
+
+ and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit
+ mov r18=ar.bsp // M2 (12 cyc)
+(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS
+ ;;
+.back_from_break_fixup:
+(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack
+ cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited?
+ br.call.sptk.many b7=ia64_syscall_setup // B
+1:
+ mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0
+ nop 0
+ bsw.1 // B (6 cyc) regs are saved, switch to bank 1
;;
- cmp.eq p8,p0=r2,r0
- mov b6=r20
+
+ ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection
+ movl r3=ia64_ret_from_syscall // X
;;
-(p8) br.call.sptk.many b6=b6 // ignore this return addr
- br.cond.sptk ia64_trace_syscall
+
+ srlz.i // M0 ensure interruption collection is on
+ mov rp=r3 // I0 set the real return addr
+(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
+
+(p15) ssm psr.i // M2 restore psr.i
+(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr)
+ br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic
// NOT REACHED
+///////////////////////////////////////////////////////////////////////
+ // On entry, we optimistically assumed that we're coming from user-space.
+ // For the rare cases where a system-call is done from within the kernel,
+ // we fix things up at this point:
+.break_fixup:
+ add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure
+ mov ar.rnat=r24 // M2 restore kernel's AR.RNAT
+ ;;
+ mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE
+ br.cond.sptk .back_from_break_fixup
END(break_fault)
.org ia64_ivt+0x3000
@@ -837,8 +878,6 @@ END(interrupt)
* - r31: saved pr
* - b0: original contents (to be saved)
* On exit:
- * - executing on bank 1 registers
- * - psr.ic enabled, interrupts restored
* - p10: TRUE if syscall is invoked with more than 8 out
* registers or r15's Nat is true
* - r1: kernel's gp
@@ -846,8 +885,11 @@ END(interrupt)
* - r8: -EINVAL if p10 is true
* - r12: points to kernel stack
* - r13: points to current task
+ * - r14: preserved (same as on entry)
+ * - p13: preserved
* - p15: TRUE if interrupts need to be re-enabled
* - ar.fpsr: set to kernel settings
+ * - b6: preserved (same as on entry)
*/
GLOBAL_ENTRY(ia64_syscall_setup)
#if PT(B6) != 0
@@ -915,10 +957,10 @@ GLOBAL_ENTRY(ia64_syscall_setup)
(p13) mov in5=-1
;;
st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
- tnat.nz p14,p0=in6
+ tnat.nz p13,p0=in6
cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
;;
- stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
+ mov r8=1
(p9) tnat.nz p10,p0=r15
adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
@@ -929,9 +971,9 @@ GLOBAL_ENTRY(ia64_syscall_setup)
mov r13=r2 // establish `current'
movl r1=__gp // establish kernel global pointer
;;
-(p14) mov in6=-1
+ st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p13) mov in6=-1
(p8) mov in7=-1
- nop.i 0
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
movl r17=FPSR_DEFAULT
@@ -1002,6 +1044,8 @@ END(dispatch_illegal_op_fault)
FAULT(17)
ENTRY(non_syscall)
+ mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER
+ ;;
SAVE_MIN_WITH_COVER
// There is no particular reason for this code to be here, other than that
@@ -1199,6 +1243,25 @@ END(disabled_fp_reg)
// 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
ENTRY(nat_consumption)
DBG_FAULT(26)
+
+ mov r16=cr.ipsr
+ mov r17=cr.isr
+ mov r31=pr // save PR
+ ;;
+ and r18=0xf,r17 // r18 = cr.ipsr.code{3:0}
+ tbit.z p6,p0=r17,IA64_ISR_NA_BIT
+ ;;
+ cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
+ dep r16=-1,r16,IA64_PSR_ED_BIT,1
+(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
+ ;;
+ mov cr.ipsr=r16 // set cr.ipsr.na
+ mov pr=r31,-1
+ ;;
+ rfi
+
+1: mov pr=r31,-1
+ ;;
FAULT(26)
END(nat_consumption)
diff --git a/arch/ia64/kernel/jprobes.S b/arch/ia64/kernel/jprobes.S
new file mode 100644
index 00000000000..b7fa3ccd2b0
--- /dev/null
+++ b/arch/ia64/kernel/jprobes.S
@@ -0,0 +1,61 @@
+/*
+ * Jprobe specific operations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-May Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ * <anil.s.keshavamurthy@intel.com> initial implementation
+ *
+ * Jprobes (a.k.a. "jump probes" which is built on-top of kprobes) allow a
+ * probe to be inserted into the beginning of a function call. The fundamental
+ * difference between a jprobe and a kprobe is the jprobe handler is executed
+ * in the same context as the target function, while the kprobe handlers
+ * are executed in interrupt context.
+ *
+ * For jprobes we initially gain control by placing a break point in the
+ * first instruction of the targeted function. When we catch that specific
+ * break, we:
+ * * set the return address to our jprobe_inst_return() function
+ * * jump to the jprobe handler function
+ *
+ * Since we fixed up the return address, the jprobe handler will return to our
+ * jprobe_inst_return() function, giving us control again. At this point we
+ * are back in the parents frame marker, so we do yet another call to our
+ * jprobe_break() function to fix up the frame marker as it would normally
+ * exist in the target function.
+ *
+ * Our jprobe_return function then transfers control back to kprobes.c by
+ * executing a break instruction using one of our reserved numbers. When we
+ * catch that break in kprobes.c, we continue like we do for a normal kprobe
+ * by single stepping the emulated instruction, and then returning execution
+ * to the correct location.
+ */
+#include <asm/asmmacro.h>
+
+ /*
+ * void jprobe_break(void)
+ */
+ENTRY(jprobe_break)
+ break.m 0x80300
+END(jprobe_break)
+
+ /*
+ * void jprobe_inst_return(void)
+ */
+GLOBAL_ENTRY(jprobe_inst_return)
+ br.call.sptk.many b0=jprobe_break
+END(jprobe_inst_return)
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
new file mode 100644
index 00000000000..884f5cd27d8
--- /dev/null
+++ b/arch/ia64/kernel/kprobes.c
@@ -0,0 +1,721 @@
+/*
+ * Kernel Probes (KProbes)
+ * arch/ia64/kernel/kprobes.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-Apr Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ * <anil.s.keshavamurthy@intel.com> adapted from i386
+ */
+
+#include <linux/config.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/preempt.h>
+#include <linux/moduleloader.h>
+
+#include <asm/pgtable.h>
+#include <asm/kdebug.h>
+#include <asm/sections.h>
+
+extern void jprobe_inst_return(void);
+
+/* kprobe_status settings */
+#define KPROBE_HIT_ACTIVE 0x00000001
+#define KPROBE_HIT_SS 0x00000002
+
+static struct kprobe *current_kprobe, *kprobe_prev;
+static unsigned long kprobe_status, kprobe_status_prev;
+static struct pt_regs jprobe_saved_regs;
+
+enum instruction_type {A, I, M, F, B, L, X, u};
+static enum instruction_type bundle_encoding[32][3] = {
+ { M, I, I }, /* 00 */
+ { M, I, I }, /* 01 */
+ { M, I, I }, /* 02 */
+ { M, I, I }, /* 03 */
+ { M, L, X }, /* 04 */
+ { M, L, X }, /* 05 */
+ { u, u, u }, /* 06 */
+ { u, u, u }, /* 07 */
+ { M, M, I }, /* 08 */
+ { M, M, I }, /* 09 */
+ { M, M, I }, /* 0A */
+ { M, M, I }, /* 0B */
+ { M, F, I }, /* 0C */
+ { M, F, I }, /* 0D */
+ { M, M, F }, /* 0E */
+ { M, M, F }, /* 0F */
+ { M, I, B }, /* 10 */
+ { M, I, B }, /* 11 */
+ { M, B, B }, /* 12 */
+ { M, B, B }, /* 13 */
+ { u, u, u }, /* 14 */
+ { u, u, u }, /* 15 */
+ { B, B, B }, /* 16 */
+ { B, B, B }, /* 17 */
+ { M, M, B }, /* 18 */
+ { M, M, B }, /* 19 */
+ { u, u, u }, /* 1A */
+ { u, u, u }, /* 1B */
+ { M, F, B }, /* 1C */
+ { M, F, B }, /* 1D */
+ { u, u, u }, /* 1E */
+ { u, u, u }, /* 1F */
+};
+
+/*
+ * In this function we check to see if the instruction
+ * is IP relative instruction and update the kprobe
+ * inst flag accordingly
+ */
+static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode,
+ unsigned long kprobe_inst, struct kprobe *p)
+{
+ p->ainsn.inst_flag = 0;
+ p->ainsn.target_br_reg = 0;
+
+ if (bundle_encoding[template][slot] == B) {
+ switch (major_opcode) {
+ case INDIRECT_CALL_OPCODE:
+ p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ break;
+ case IP_RELATIVE_PREDICT_OPCODE:
+ case IP_RELATIVE_BRANCH_OPCODE:
+ p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+ break;
+ case IP_RELATIVE_CALL_OPCODE:
+ p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+ p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ break;
+ }
+ } else if (bundle_encoding[template][slot] == X) {
+ switch (major_opcode) {
+ case LONG_CALL_OPCODE:
+ p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ break;
+ }
+ }
+ return;
+}
+
+/*
+ * In this function we check to see if the instruction
+ * on which we are inserting kprobe is supported.
+ * Returns 0 if supported
+ * Returns -EINVAL if unsupported
+ */
+static int unsupported_inst(uint template, uint slot, uint major_opcode,
+ unsigned long kprobe_inst, struct kprobe *p)
+{
+ unsigned long addr = (unsigned long)p->addr;
+
+ if (bundle_encoding[template][slot] == I) {
+ switch (major_opcode) {
+ case 0x0: //I_UNIT_MISC_OPCODE:
+ /*
+ * Check for Integer speculation instruction
+ * - Bit 33-35 to be equal to 0x1
+ */
+ if (((kprobe_inst >> 33) & 0x7) == 1) {
+ printk(KERN_WARNING
+ "Kprobes on speculation inst at <0x%lx> not supported\n",
+ addr);
+ return -EINVAL;
+ }
+
+ /*
+ * IP relative mov instruction
+ * - Bit 27-35 to be equal to 0x30
+ */
+ if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
+ printk(KERN_WARNING
+ "Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
+ addr);
+ return -EINVAL;
+
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * In this function we check to see if the instruction
+ * (qp) cmpx.crel.ctype p1,p2=r2,r3
+ * on which we are inserting kprobe is cmp instruction
+ * with ctype as unc.
+ */
+static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
+unsigned long kprobe_inst)
+{
+ cmp_inst_t cmp_inst;
+ uint ctype_unc = 0;
+
+ if (!((bundle_encoding[template][slot] == I) ||
+ (bundle_encoding[template][slot] == M)))
+ goto out;
+
+ if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
+ (major_opcode == 0xE)))
+ goto out;
+
+ cmp_inst.l = kprobe_inst;
+ if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
+ /* Integere compare - Register Register (A6 type)*/
+ if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
+ &&(cmp_inst.f.c == 1))
+ ctype_unc = 1;
+ } else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
+ /* Integere compare - Immediate Register (A8 type)*/
+ if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
+ ctype_unc = 1;
+ }
+out:
+ return ctype_unc;
+}
+
+/*
+ * In this function we override the bundle with
+ * the break instruction at the given slot.
+ */
+static void prepare_break_inst(uint template, uint slot, uint major_opcode,
+ unsigned long kprobe_inst, struct kprobe *p)
+{
+ unsigned long break_inst = BREAK_INST;
+ bundle_t *bundle = &p->ainsn.insn.bundle;
+
+ /*
+ * Copy the original kprobe_inst qualifying predicate(qp)
+ * to the break instruction iff !is_cmp_ctype_unc_inst
+ * because for cmp instruction with ctype equal to unc,
+ * which is a special instruction always needs to be
+ * executed regradless of qp
+ */
+ if (!is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst))
+ break_inst |= (0x3f & kprobe_inst);
+
+ switch (slot) {
+ case 0:
+ bundle->quad0.slot0 = break_inst;
+ break;
+ case 1:
+ bundle->quad0.slot1_p0 = break_inst;
+ bundle->quad1.slot1_p1 = break_inst >> (64-46);
+ break;
+ case 2:
+ bundle->quad1.slot2 = break_inst;
+ break;
+ }
+
+ /*
+ * Update the instruction flag, so that we can
+ * emulate the instruction properly after we
+ * single step on original instruction
+ */
+ update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
+}
+
+static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
+ unsigned long *kprobe_inst, uint *major_opcode)
+{
+ unsigned long kprobe_inst_p0, kprobe_inst_p1;
+ unsigned int template;
+
+ template = bundle->quad0.template;
+
+ switch (slot) {
+ case 0:
+ *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
+ *kprobe_inst = bundle->quad0.slot0;
+ break;
+ case 1:
+ *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
+ kprobe_inst_p0 = bundle->quad0.slot1_p0;
+ kprobe_inst_p1 = bundle->quad1.slot1_p1;
+ *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
+ break;
+ case 2:
+ *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
+ *kprobe_inst = bundle->quad1.slot2;
+ break;
+ }
+}
+
+/* Returns non-zero if the addr is in the Interrupt Vector Table */
+static inline int in_ivt_functions(unsigned long addr)
+{
+ return (addr >= (unsigned long)__start_ivt_text
+ && addr < (unsigned long)__end_ivt_text);
+}
+
+static int valid_kprobe_addr(int template, int slot, unsigned long addr)
+{
+ if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
+ printk(KERN_WARNING "Attempting to insert unaligned kprobe "
+ "at 0x%lx\n", addr);
+ return -EINVAL;
+ }
+
+ if (in_ivt_functions(addr)) {
+ printk(KERN_WARNING "Kprobes can't be inserted inside "
+ "IVT functions at 0x%lx\n", addr);
+ return -EINVAL;
+ }
+
+ if (slot == 1 && bundle_encoding[template][1] != L) {
+ printk(KERN_WARNING "Inserting kprobes on slot #1 "
+ "is not supported\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline void save_previous_kprobe(void)
+{
+ kprobe_prev = current_kprobe;
+ kprobe_status_prev = kprobe_status;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+ current_kprobe = kprobe_prev;
+ kprobe_status = kprobe_status_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p)
+{
+ current_kprobe = p;
+}
+
+static void kretprobe_trampoline(void)
+{
+}
+
+/*
+ * At this point the target function has been tricked into
+ * returning into our trampoline. Lookup the associated instance
+ * and then:
+ * - call the handler function
+ * - cleanup by marking the instance as unused
+ * - long jump back to the original return address
+ */
+int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head;
+ struct hlist_node *node, *tmp;
+ unsigned long orig_ret_address = 0;
+ unsigned long trampoline_address =
+ ((struct fnptr *)kretprobe_trampoline)->ip;
+
+ head = kretprobe_inst_table_head(current);
+
+ /*
+ * It is possible to have multiple instances associated with a given
+ * task either because an multiple functions in the call path
+ * have a return probe installed on them, and/or more then one return
+ * return probe was registered for a target function.
+ *
+ * We can handle this because:
+ * - instances are always inserted at the head of the list
+ * - when multiple return probes are registered for the same
+ * function, the first instance's ret_addr will point to the
+ * real return address, and all the rest will point to
+ * kretprobe_trampoline
+ */
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler)
+ ri->rp->handler(ri, regs);
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
+ recycle_rp_inst(ri);
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+ regs->cr_iip = orig_ret_address;
+
+ unlock_kprobes();
+ preempt_enable_no_resched();
+
+ /*
+ * By returning a non-zero value, we are telling
+ * kprobe_handler() that we have handled unlocking
+ * and re-enabling preemption.
+ */
+ return 1;
+}
+
+void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri;
+
+ if ((ri = get_free_rp_inst(rp)) != NULL) {
+ ri->rp = rp;
+ ri->task = current;
+ ri->ret_addr = (kprobe_opcode_t *)regs->b0;
+
+ /* Replace the return addr with trampoline addr */
+ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
+
+ add_rp_inst(ri);
+ } else {
+ rp->nmissed++;
+ }
+}
+
+int arch_prepare_kprobe(struct kprobe *p)
+{
+ unsigned long addr = (unsigned long) p->addr;
+ unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
+ unsigned long kprobe_inst=0;
+ unsigned int slot = addr & 0xf, template, major_opcode = 0;
+ bundle_t *bundle = &p->ainsn.insn.bundle;
+
+ memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t));
+ memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t));
+
+ template = bundle->quad0.template;
+
+ if(valid_kprobe_addr(template, slot, addr))
+ return -EINVAL;
+
+ /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
+ if (slot == 1 && bundle_encoding[template][1] == L)
+ slot++;
+
+ /* Get kprobe_inst and major_opcode from the bundle */
+ get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
+
+ if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p))
+ return -EINVAL;
+
+ prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
+
+ return 0;
+}
+
+void arch_arm_kprobe(struct kprobe *p)
+{
+ unsigned long addr = (unsigned long)p->addr;
+ unsigned long arm_addr = addr & ~0xFULL;
+
+ memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t));
+ flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
+}
+
+void arch_disarm_kprobe(struct kprobe *p)
+{
+ unsigned long addr = (unsigned long)p->addr;
+ unsigned long arm_addr = addr & ~0xFULL;
+
+ /* p->opcode contains the original unaltered bundle */
+ memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t));
+ flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
+}
+
+/*
+ * We are resuming execution after a single step fault, so the pt_regs
+ * structure reflects the register state after we executed the instruction
+ * located in the kprobe (p->ainsn.insn.bundle). We still need to adjust
+ * the ip to point back to the original stack address. To set the IP address
+ * to original stack address, handle the case where we need to fixup the
+ * relative IP address and/or fixup branch register.
+ */
+static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+{
+ unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
+ unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
+ unsigned long template;
+ int slot = ((unsigned long)p->addr & 0xf);
+
+ template = p->opcode.bundle.quad0.template;
+
+ if (slot == 1 && bundle_encoding[template][1] == L)
+ slot = 2;
+
+ if (p->ainsn.inst_flag) {
+
+ if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
+ /* Fix relative IP address */
+ regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
+ }
+
+ if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
+ /*
+ * Fix target branch register, software convention is
+ * to use either b0 or b6 or b7, so just checking
+ * only those registers
+ */
+ switch (p->ainsn.target_br_reg) {
+ case 0:
+ if ((regs->b0 == bundle_addr) ||
+ (regs->b0 == bundle_addr + 0x10)) {
+ regs->b0 = (regs->b0 - bundle_addr) +
+ resume_addr;
+ }
+ break;
+ case 6:
+ if ((regs->b6 == bundle_addr) ||
+ (regs->b6 == bundle_addr + 0x10)) {
+ regs->b6 = (regs->b6 - bundle_addr) +
+ resume_addr;
+ }
+ break;
+ case 7:
+ if ((regs->b7 == bundle_addr) ||
+ (regs->b7 == bundle_addr + 0x10)) {
+ regs->b7 = (regs->b7 - bundle_addr) +
+ resume_addr;
+ }
+ break;
+ } /* end switch */
+ }
+ goto turn_ss_off;
+ }
+
+ if (slot == 2) {
+ if (regs->cr_iip == bundle_addr + 0x10) {
+ regs->cr_iip = resume_addr + 0x10;
+ }
+ } else {
+ if (regs->cr_iip == bundle_addr) {
+ regs->cr_iip = resume_addr;
+ }
+ }
+
+turn_ss_off:
+ /* Turn off Single Step bit */
+ ia64_psr(regs)->ss = 0;
+}
+
+static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
+{
+ unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
+ unsigned long slot = (unsigned long)p->addr & 0xf;
+
+ /* Update instruction pointer (IIP) and slot number (IPSR.ri) */
+ regs->cr_iip = bundle_addr & ~0xFULL;
+
+ if (slot > 2)
+ slot = 0;
+
+ ia64_psr(regs)->ri = slot;
+
+ /* turn on single stepping */
+ ia64_psr(regs)->ss = 1;
+}
+
+static int pre_kprobes_handler(struct die_args *args)
+{
+ struct kprobe *p;
+ int ret = 0;
+ struct pt_regs *regs = args->regs;
+ kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
+
+ preempt_disable();
+
+ /* Handle recursion cases */
+ if (kprobe_running()) {
+ p = get_kprobe(addr);
+ if (p) {
+ if (kprobe_status == KPROBE_HIT_SS) {
+ unlock_kprobes();
+ goto no_kprobe;
+ }
+ /* We have reentered the pre_kprobe_handler(), since
+ * another probe was hit while within the handler.
+ * We here save the original kprobes variables and
+ * just single step on the instruction of the new probe
+ * without calling any user handlers.
+ */
+ save_previous_kprobe();
+ set_current_kprobe(p);
+ p->nmissed++;
+ prepare_ss(p, regs);
+ kprobe_status = KPROBE_REENTER;
+ return 1;
+ } else if (args->err == __IA64_BREAK_JPROBE) {
+ /*
+ * jprobe instrumented function just completed
+ */
+ p = current_kprobe;
+ if (p->break_handler && p->break_handler(p, regs)) {
+ goto ss_probe;
+ }
+ } else {
+ /* Not our break */
+ goto no_kprobe;
+ }
+ }
+
+ lock_kprobes();
+ p = get_kprobe(addr);
+ if (!p) {
+ unlock_kprobes();
+ goto no_kprobe;
+ }
+
+ kprobe_status = KPROBE_HIT_ACTIVE;
+ set_current_kprobe(p);
+
+ if (p->pre_handler && p->pre_handler(p, regs))
+ /*
+ * Our pre-handler is specifically requesting that we just
+ * do a return. This is used for both the jprobe pre-handler
+ * and the kretprobe trampoline
+ */
+ return 1;
+
+ss_probe:
+ prepare_ss(p, regs);
+ kprobe_status = KPROBE_HIT_SS;
+ return 1;
+
+no_kprobe:
+ preempt_enable_no_resched();
+ return ret;
+}
+
+static int post_kprobes_handler(struct pt_regs *regs)
+{
+ if (!kprobe_running())
+ return 0;
+
+ if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+ kprobe_status = KPROBE_HIT_SSDONE;
+ current_kprobe->post_handler(current_kprobe, regs, 0);
+ }
+
+ resume_execution(current_kprobe, regs);
+
+ /*Restore back the original saved kprobes variables and continue. */
+ if (kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe();
+ goto out;
+ }
+
+ unlock_kprobes();
+
+out:
+ preempt_enable_no_resched();
+ return 1;
+}
+
+static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+{
+ if (!kprobe_running())
+ return 0;
+
+ if (current_kprobe->fault_handler &&
+ current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+ return 1;
+
+ if (kprobe_status & KPROBE_HIT_SS) {
+ resume_execution(current_kprobe, regs);
+ unlock_kprobes();
+ preempt_enable_no_resched();
+ }
+
+ return 0;
+}
+
+int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
+ void *data)
+{
+ struct die_args *args = (struct die_args *)data;
+ switch(val) {
+ case DIE_BREAK:
+ if (pre_kprobes_handler(args))
+ return NOTIFY_STOP;
+ break;
+ case DIE_SS:
+ if (post_kprobes_handler(args->regs))
+ return NOTIFY_STOP;
+ break;
+ case DIE_PAGE_FAULT:
+ if (kprobes_fault_handler(args->regs, args->trapnr))
+ return NOTIFY_STOP;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+ unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
+
+ /* save architectural state */
+ jprobe_saved_regs = *regs;
+
+ /* after rfi, execute the jprobe instrumented function */
+ regs->cr_iip = addr & ~0xFULL;
+ ia64_psr(regs)->ri = addr & 0xf;
+ regs->r1 = ((struct fnptr *)(jp->entry))->gp;
+
+ /*
+ * fix the return address to our jprobe_inst_return() function
+ * in the jprobes.S file
+ */
+ regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
+
+ return 1;
+}
+
+int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ *regs = jprobe_saved_regs;
+ return 1;
+}
+
+static struct kprobe trampoline_p = {
+ .pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+ trampoline_p.addr =
+ (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
+ return register_kprobe(&trampoline_p);
+}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 736e328b5e6..4ebbf397438 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -271,7 +271,7 @@ ia64_mca_log_sal_error_record(int sal_info_type)
#ifdef CONFIG_ACPI
-static int cpe_vector = -1;
+int cpe_vector = -1;
static irqreturn_t
ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
new file mode 100644
index 00000000000..a68ce667809
--- /dev/null
+++ b/arch/ia64/kernel/numa.c
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * ia64 kernel NUMA specific stuff
+ *
+ * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
+ * Copyright (C) 2004 Silicon Graphics, Inc.
+ * Jesse Barnes <jbarnes@sgi.com>
+ */
+#include <linux/config.h>
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+
+u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_to_node_map);
+
+cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+
+/**
+ * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
+ *
+ * Build cpu to node mapping and initialize the per node cpu masks using
+ * info from the node_cpuid array handed to us by ACPI.
+ */
+void __init build_cpu_to_node_map(void)
+{
+ int cpu, i, node;
+
+ for(node=0; node < MAX_NUMNODES; node++)
+ cpus_clear(node_to_cpu_mask[node]);
+
+ for(cpu = 0; cpu < NR_CPUS; ++cpu) {
+ node = -1;
+ for (i = 0; i < NR_CPUS; ++i)
+ if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
+ node = node_cpuid[i].nid;
+ break;
+ }
+ cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
+ if (node >= 0)
+ cpu_set(cpu, node_to_cpu_mask[node]);
+ }
+}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 6407bff6bfd..b8ebb8e427e 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -37,7 +37,6 @@
#include <linux/vfs.h>
#include <linux/pagemap.h>
#include <linux/mount.h>
-#include <linux/version.h>
#include <linux/bitops.h>
#include <asm/errno.h>
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index ebb71f3d6d1..051e050359e 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -27,6 +27,7 @@
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/kprobes.h>
#include <asm/cpu.h>
#include <asm/delay.h>
@@ -178,7 +179,7 @@ static int can_do_pal_halt = 1;
static int __init nohalt_setup(char * str)
{
- pal_halt = 0;
+ pal_halt = can_do_pal_halt = 0;
return 1;
}
__setup("nohalt", nohalt_setup);
@@ -195,6 +196,7 @@ update_pal_halt_status(int status)
void
default_idle (void)
{
+ local_irq_enable();
while (!need_resched())
if (can_do_pal_halt)
safe_halt();
@@ -707,6 +709,13 @@ kernel_thread_helper (int (*fn)(void *), void *arg)
void
flush_thread (void)
{
+ /*
+ * Remove function-return probe instances associated with this task
+ * and put them back on the free list. Do not insert an exit probe for
+ * this function, it will be disabled by kprobe_flush_task if you do.
+ */
+ kprobe_flush_task(current);
+
/* drop floating-point and debug-register state if it exists: */
current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
ia64_drop_fpu(current);
@@ -721,6 +730,14 @@ flush_thread (void)
void
exit_thread (void)
{
+
+ /*
+ * Remove function-return probe instances associated with this task
+ * and put them back on the free list. Do not insert an exit probe for
+ * this function, it will be disabled by kprobe_flush_task if you do.
+ */
+ kprobe_flush_task(current);
+
ia64_drop_fpu(current);
#ifdef CONFIG_PERFMON
/* if needed, stop monitoring and flush state to perfmon context */
@@ -790,16 +807,12 @@ machine_restart (char *restart_cmd)
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
}
-EXPORT_SYMBOL(machine_restart);
-
void
machine_halt (void)
{
cpu_halt();
}
-EXPORT_SYMBOL(machine_halt);
-
void
machine_power_off (void)
{
@@ -808,4 +821,3 @@ machine_power_off (void)
machine_halt();
}
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 575a8f657b3..bbb8bc7c055 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -725,12 +725,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
break;
}
+ /*
+ * Note: at the time of this call, the target task is blocked
+ * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
+ * (aka, "pLvSys") we redirect execution from
+ * .work_pending_syscall_end to .work_processed_kernel.
+ */
unw_get_pr(&prev_info, &pr);
- pr &= ~(1UL << PRED_SYSCALL);
+ pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
pr |= (1UL << PRED_NON_SYSCALL);
unw_set_pr(&prev_info, pr);
pt->cr_ifs = (1UL << 63) | cfm;
+ /*
+ * Clear the memory that is NOT written on syscall-entry to
+ * ensure we do not leak kernel-state to user when execution
+ * resumes.
+ */
+ pt->r2 = 0;
+ pt->r3 = 0;
+ pt->r14 = 0;
+ memset(&pt->r16, 0, 16*8); /* clear r16-r31 */
+ memset(&pt->f6, 0, 6*16); /* clear f6-f11 */
+ pt->b7 = 0;
+ pt->ar_ccv = 0;
+ pt->ar_csd = 0;
+ pt->ar_ssd = 0;
}
static int
@@ -945,6 +965,13 @@ access_uarea (struct task_struct *child, unsigned long addr,
*data = (pt->cr_ipsr & IPSR_MASK);
return 0;
+ case PT_AR_RSC:
+ if (write_access)
+ pt->ar_rsc = *data | (3 << 2); /* force PL3 */
+ else
+ *data = pt->ar_rsc;
+ return 0;
+
case PT_AR_RNAT:
urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
rnat_addr = (long) ia64_rse_rnat_addr((long *)
@@ -996,9 +1023,6 @@ access_uarea (struct task_struct *child, unsigned long addr,
case PT_AR_BSPSTORE:
ptr = pt_reg_addr(pt, ar_bspstore);
break;
- case PT_AR_RSC:
- ptr = pt_reg_addr(pt, ar_rsc);
- break;
case PT_AR_UNAT:
ptr = pt_reg_addr(pt, ar_unat);
break;
@@ -1234,7 +1258,7 @@ ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
static long
ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
{
- unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
+ unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
struct unw_frame_info info;
struct switch_stack *sw;
struct ia64_fpreg fpval;
@@ -1267,7 +1291,7 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
/* app regs */
retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
- retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
+ retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
@@ -1365,6 +1389,7 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
retval |= __get_user(nat_bits, &ppr->nat);
retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
+ retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
retval |= access_uarea(child, PT_AR_EC, &ec, 1);
retval |= access_uarea(child, PT_AR_LC, &lc, 1);
retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index d14692e0920..84f89da7c64 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -20,6 +20,7 @@
* 02/01/00 R.Seth fixed get_cpuinfo for SMP
* 01/07/99 S.Eranian added the support for command line argument
* 06/24/99 W.Drummond added boot_cpu_data.
+ * 05/28/05 Z. Menyhart Dynamic stride size for "flush_icache_range()"
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -40,6 +41,8 @@
#include <linux/serial_core.h>
#include <linux/efi.h>
#include <linux/initrd.h>
+#include <linux/platform.h>
+#include <linux/pm.h>
#include <asm/ia32.h>
#include <asm/machvec.h>
@@ -72,6 +75,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
unsigned long ia64_cycles_per_usec;
struct ia64_boot_param *ia64_boot_param;
struct screen_info screen_info;
+unsigned long vga_console_iobase;
+unsigned long vga_console_membase;
unsigned long ia64_max_cacheline_size;
unsigned long ia64_iobase; /* virtual address for I/O accesses */
@@ -81,6 +86,13 @@ EXPORT_SYMBOL(io_space);
unsigned int num_io_spaces;
/*
+ * "flush_icache_range()" needs to know what processor dependent stride size to use
+ * when it makes i-cache(s) coherent with d-caches.
+ */
+#define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */
+unsigned long ia64_i_cache_stride_shift = ~0;
+
+/*
* The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This
* mask specifies a mask of address bits that must be 0 in order for two buffers to be
* mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
@@ -273,23 +285,25 @@ io_port_init (void)
static inline int __init
early_console_setup (char *cmdline)
{
+ int earlycons = 0;
+
#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
{
extern int sn_serial_console_early_setup(void);
if (!sn_serial_console_early_setup())
- return 0;
+ earlycons++;
}
#endif
#ifdef CONFIG_EFI_PCDP
if (!efi_setup_pcdp_console(cmdline))
- return 0;
+ earlycons++;
#endif
#ifdef CONFIG_SERIAL_8250_CONSOLE
if (!early_serial_console_init(cmdline))
- return 0;
+ earlycons++;
#endif
- return -1;
+ return (earlycons) ? 0 : -1;
}
static inline void
@@ -622,6 +636,12 @@ setup_per_cpu_areas (void)
/* start_kernel() requires this... */
}
+/*
+ * Calculate the max. cache line size.
+ *
+ * In addition, the minimum of the i-cache stride sizes is calculated for
+ * "flush_icache_range()".
+ */
static void
get_max_cacheline_size (void)
{
@@ -635,6 +655,8 @@ get_max_cacheline_size (void)
printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
__FUNCTION__, status);
max = SMP_CACHE_BYTES;
+ /* Safest setup for "flush_icache_range()" */
+ ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
goto out;
}
@@ -643,14 +665,31 @@ get_max_cacheline_size (void)
&cci);
if (status != 0) {
printk(KERN_ERR
- "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",
+ "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
__FUNCTION__, l, status);
max = SMP_CACHE_BYTES;
+ /* The safest setup for "flush_icache_range()" */
+ cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+ cci.pcci_unified = 1;
}
line_size = 1 << cci.pcci_line_size;
if (line_size > max)
max = line_size;
- }
+ if (!cci.pcci_unified) {
+ status = ia64_pal_cache_config_info(l,
+ /* cache_type (instruction)= */ 1,
+ &cci);
+ if (status != 0) {
+ printk(KERN_ERR
+ "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
+ __FUNCTION__, l, status);
+ /* The safest setup for "flush_icache_range()" */
+ cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+ }
+ }
+ if (cci.pcci_stride < ia64_i_cache_stride_shift)
+ ia64_i_cache_stride_shift = cci.pcci_stride;
+ }
out:
if (max > ia64_max_cacheline_size)
ia64_max_cacheline_size = max;
@@ -779,6 +818,7 @@ cpu_init (void)
/* size of physical stacked register partition plus 8 bytes: */
__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
platform_cpu_init();
+ pm_idle = default_idle;
}
void
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 499b7e5317c..b8a0a7d257a 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, long arg2,
static long
restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
{
- unsigned long ip, flags, nat, um, cfm;
+ unsigned long ip, flags, nat, um, cfm, rsc;
long err;
/* Always make any pending restarted system calls return -EINTR */
@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
err |= __get_user(ip, &sc->sc_ip); /* instruction pointer */
err |= __get_user(cfm, &sc->sc_cfm);
err |= __get_user(um, &sc->sc_um); /* user mask */
- err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
+ err |= __get_user(rsc, &sc->sc_ar_rsc);
err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8); /* r15 */
scr->pt.cr_ifs = cfm | (1UL << 63);
+ scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
/* establish new instruction pointer: */
scr->pt.cr_iip = ip & ~0x3UL;
@@ -142,6 +143,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
__copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
psr->mfh = 0; /* drop signal handler's fph contents... */
+ preempt_disable();
if (psr->dfh)
ia64_drop_fpu(current);
else {
@@ -149,6 +151,7 @@ restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
__ia64_load_fpu(current->thread.fph);
ia64_set_local_fpu_owner(current);
}
+ preempt_enable();
}
return err;
}
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index 953095e2ce1..0166a984709 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -231,13 +231,16 @@ smp_flush_tlb_all (void)
void
smp_flush_tlb_mm (struct mm_struct *mm)
{
+ preempt_disable();
/* this happens for the common case of a single-threaded fork(): */
if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
{
local_finish_flush_tlb_mm(mm);
+ preempt_enable();
return;
}
+ preempt_enable();
/*
* We could optimize this further by using mm->cpu_vm_mask to track which CPUs
* have been running in the address space. It's not clear that this is worth the
@@ -269,7 +272,7 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int
int me = get_cpu(); /* prevent preemption and reschedule on another processor */
if (cpuid == me) {
- printk("%s: trying to call self\n", __FUNCTION__);
+ printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__);
put_cpu();
return -EBUSY;
}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 3865f088ffa..7d72c0d872b 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -346,6 +346,7 @@ smp_callin (void)
lock_ipi_calllock();
cpu_set(cpuid, cpu_online_map);
unlock_ipi_calllock();
+ per_cpu(cpu_state, cpuid) = CPU_ONLINE;
smp_setup_percpu_timer();
@@ -524,47 +525,6 @@ smp_build_cpu_map (void)
}
}
-#ifdef CONFIG_NUMA
-
-/* on which node is each logical CPU (one cacheline even for 64 CPUs) */
-u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_to_node_map);
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
-
-/*
- * Build cpu to node mapping and initialize the per node cpu masks.
- */
-void __init
-build_cpu_to_node_map (void)
-{
- int cpu, i, node;
-
- for(node=0; node<MAX_NUMNODES; node++)
- cpus_clear(node_to_cpu_mask[node]);
- for(cpu = 0; cpu < NR_CPUS; ++cpu) {
- /*
- * All Itanium NUMA platforms I know use ACPI, so maybe we
- * can drop this ifdef completely. [EF]
- */
-#ifdef CONFIG_ACPI_NUMA
- node = -1;
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
- node = node_cpuid[i].nid;
- break;
- }
-#else
-# error Fixme: Dunno how to build CPU-to-node map.
-#endif
- cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
- if (node >= 0)
- cpu_set(cpu, node_to_cpu_mask[node]);
- }
-}
-
-#endif /* CONFIG_NUMA */
-
/*
* Cycle through the APs sending Wakeup IPIs to boot each.
*/
@@ -611,6 +571,7 @@ void __devinit smp_prepare_boot_cpu(void)
{
cpu_set(smp_processor_id(), cpu_online_map);
cpu_set(smp_processor_id(), cpu_callin_map);
+ per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
}
/*
@@ -688,6 +649,7 @@ int __cpu_disable(void)
return -EBUSY;
remove_siblinginfo(cpu);
+ cpu_clear(cpu, cpu_online_map);
fixup_irqs();
local_flush_tlb_all();
cpu_clear(cpu, cpu_callin_map);
@@ -774,6 +736,7 @@ __cpu_up (unsigned int cpu)
if (cpu_isset(cpu, cpu_callin_map))
return -EINVAL;
+ per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
/* Processor goes to start_secondary(), sets online flag */
ret = do_boot_cpu(sapicid, cpu);
if (ret < 0)
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index f1aafd4c05f..92ff46ad21e 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,6 +36,15 @@ int arch_register_cpu(int num)
parent = &sysfs_nodes[cpu_to_node(num)];
#endif /* CONFIG_NUMA */
+#ifdef CONFIG_ACPI_BOOT
+ /*
+ * If CPEI cannot be re-targetted, and this is
+ * CPEI target, then dont create the control file
+ */
+ if (!can_cpei_retarget() && is_cpu_cpei_target(num))
+ sysfs_cpus[num].cpu.no_control = 1;
+#endif
+
return register_cpu(&sysfs_cpus[num].cpu, num, parent);
}
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 1861173bd4f..4440c8343fa 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -21,12 +21,26 @@
#include <asm/intrinsics.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
+#include <asm/kdebug.h>
extern spinlock_t timerlist_lock;
fpswa_interface_t *fpswa_interface;
EXPORT_SYMBOL(fpswa_interface);
+struct notifier_block *ia64die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ int err = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&die_notifier_lock, flags);
+ err = notifier_chain_register(&ia64die_chain, nb);
+ spin_unlock_irqrestore(&die_notifier_lock, flags);
+ return err;
+}
+
void __init
trap_init (void)
{
@@ -76,14 +90,16 @@ die (const char *str, struct pt_regs *regs, long err)
.lock_owner_depth = 0
};
static int die_counter;
+ int cpu = get_cpu();
- if (die.lock_owner != smp_processor_id()) {
+ if (die.lock_owner != cpu) {
console_verbose();
spin_lock_irq(&die.lock);
- die.lock_owner = smp_processor_id();
+ die.lock_owner = cpu;
die.lock_owner_depth = 0;
bust_spinlocks(1);
}
+ put_cpu();
if (++die.lock_owner_depth < 3) {
printk("%s[%d]: %s %ld [%d]\n",
@@ -137,6 +153,10 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
switch (break_num) {
case 0: /* unknown error (used by GCC for __builtin_abort()) */
+ if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
+ == NOTIFY_STOP) {
+ return;
+ }
die_if_kernel("bugcheck!", regs, break_num);
sig = SIGILL; code = ILL_ILLOPC;
break;
@@ -189,6 +209,15 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
sig = SIGILL; code = __ILL_BNDMOD;
break;
+ case 0x80200:
+ case 0x80300:
+ if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
+ == NOTIFY_STOP) {
+ return;
+ }
+ sig = SIGTRAP; code = TRAP_BRKPT;
+ break;
+
default:
if (break_num < 0x40000 || break_num > 0x100000)
die_if_kernel("Bad break", regs, break_num);
@@ -548,7 +577,11 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
#endif
break;
case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
- case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
+ case 36:
+ if (notify_die(DIE_SS, "ss", &regs, vector,
+ vector, SIGTRAP) == NOTIFY_STOP)
+ return;
+ siginfo.si_code = TRAP_TRACE; ifa = 0; break;
}
siginfo.si_signo = SIGTRAP;
siginfo.si_errno = 0;
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index 2776a074c6f..3288be47bc7 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -362,7 +362,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char
if (info->pri_unat_loc)
nat_addr = info->pri_unat_loc;
else
- nat_addr = &info->sw->ar_unat;
+ nat_addr = &info->sw->caller_unat;
nat_mask = (1UL << ((long) addr & 0x1f8)/8);
}
} else {
@@ -524,7 +524,7 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int
case UNW_AR_UNAT:
addr = info->unat_loc;
if (!addr)
- addr = &info->sw->ar_unat;
+ addr = &info->sw->caller_unat;
break;
case UNW_AR_LC:
@@ -1775,7 +1775,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state)
case UNW_INSN_SETNAT_MEMSTK:
if (!state->pri_unat_loc)
- state->pri_unat_loc = &state->sw->ar_unat;
+ state->pri_unat_loc = &state->sw->caller_unat;
/* register off. is a multiple of 8, so the least 3 bits (type) are 0 */
s[dst+1] = ((unsigned long) state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK;
break;
@@ -2243,11 +2243,11 @@ unw_init (void)
if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
unw_hash_index_t_is_too_narrow();
- unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(AR_UNAT);
+ unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(CALLER_UNAT);
unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE);
- unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_UNAT);
+ unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_PFS);
unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0);
- unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(AR_UNAT);
+ unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(CALLER_UNAT);
unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR);
unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC);
unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR);
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index b9f0db4c1b0..a676e79e068 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -8,6 +8,11 @@
#define LOAD_OFFSET (KERNEL_START - KERNEL_TR_PAGE_SIZE)
#include <asm-generic/vmlinux.lds.h>
+#define IVT_TEXT \
+ VMLINUX_SYMBOL(__start_ivt_text) = .; \
+ *(.text.ivt) \
+ VMLINUX_SYMBOL(__end_ivt_text) = .;
+
OUTPUT_FORMAT("elf64-ia64-little")
OUTPUT_ARCH(ia64)
ENTRY(phys_start)
@@ -39,7 +44,7 @@ SECTIONS
.text : AT(ADDR(.text) - LOAD_OFFSET)
{
- *(.text.ivt)
+ IVT_TEXT
*(.text)
SCHED_TEXT
LOCK_TEXT
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
index a1af9146cfd..3e2cfa2c6d3 100644
--- a/arch/ia64/lib/flush.S
+++ b/arch/ia64/lib/flush.S
@@ -3,37 +3,59 @@
*
* Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 05/28/05 Zoltan Menyhart Dynamic stride size
*/
+
#include <asm/asmmacro.h>
-#include <asm/page.h>
+
/*
* flush_icache_range(start,end)
- * Must flush range from start to end-1 but nothing else (need to
+ *
+ * Make i-cache(s) coherent with d-caches.
+ *
+ * Must deal with range from start to end-1 but nothing else (need to
* be careful not to touch addresses that may be unmapped).
+ *
+ * Note: "in0" and "in1" are preserved for debugging purposes.
*/
GLOBAL_ENTRY(flush_icache_range)
+
.prologue
- alloc r2=ar.pfs,2,0,0,0
- sub r8=in1,in0,1
+ alloc r2=ar.pfs,2,0,0,0
+ movl r3=ia64_i_cache_stride_shift
+ mov r21=1
+ ;;
+ ld8 r20=[r3] // r20: stride shift
+ sub r22=in1,r0,1 // last byte address
;;
- shr.u r8=r8,5 // we flush 32 bytes per iteration
- .save ar.lc, r3
- mov r3=ar.lc // save ar.lc
+ shr.u r23=in0,r20 // start / (stride size)
+ shr.u r22=r22,r20 // (last byte address) / (stride size)
+ shl r21=r21,r20 // r21: stride size of the i-cache(s)
+ ;;
+ sub r8=r22,r23 // number of strides - 1
+ shl r24=r23,r20 // r24: addresses for "fc.i" =
+ // "start" rounded down to stride boundary
+ .save ar.lc,r3
+ mov r3=ar.lc // save ar.lc
;;
.body
-
- mov ar.lc=r8
+ mov ar.lc=r8
;;
-.Loop: fc.i in0 // issuable on M2 only
- add in0=32,in0
+ /*
+ * 32 byte aligned loop, even number of (actually 2) bundles
+ */
+.Loop: fc.i r24 // issuable on M0 only
+ add r24=r21,r24 // we flush "stride size" bytes per iteration
+ nop.i 0
br.cloop.sptk.few .Loop
;;
sync.i
;;
srlz.i
;;
- mov ar.lc=r3 // restore ar.lc
+ mov ar.lc=r3 // restore ar.lc
br.ret.sptk.many rp
END(flush_icache_range)
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index c0071092939..b5c90e54819 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -44,150 +44,7 @@ struct early_node_data {
};
static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
-
-/**
- * reassign_cpu_only_nodes - called from find_memory to move CPU-only nodes to a memory node
- *
- * This function will move nodes with only CPUs (no memory)
- * to a node with memory which is at the minimum numa_slit distance.
- * Any reassigments will result in the compression of the nodes
- * and renumbering the nid values where appropriate.
- * The static declarations below are to avoid large stack size which
- * makes the code not re-entrant.
- */
-static void __init reassign_cpu_only_nodes(void)
-{
- struct node_memblk_s *p;
- int i, j, k, nnode, nid, cpu, cpunid, pxm;
- u8 cslit, slit;
- static DECLARE_BITMAP(nodes_with_mem, MAX_NUMNODES) __initdata;
- static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata;
- static int node_flip[MAX_NUMNODES] __initdata;
- static int old_nid_map[NR_CPUS] __initdata;
-
- for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
- if (!test_bit(p->nid, (void *) nodes_with_mem)) {
- set_bit(p->nid, (void *) nodes_with_mem);
- nnode++;
- }
-
- /*
- * All nids with memory.
- */
- if (nnode == num_online_nodes())
- return;
-
- /*
- * Change nids and attempt to migrate CPU-only nodes
- * to the best numa_slit (closest neighbor) possible.
- * For reassigned CPU nodes a nid can't be arrived at
- * until after this loop because the target nid's new
- * identity might not have been established yet. So
- * new nid values are fabricated above num_online_nodes() and
- * mapped back later to their true value.
- */
- /* MCD - This code is a bit complicated, but may be unnecessary now.
- * We can now handle much more interesting node-numbering.
- * The old requirement that 0 <= nid <= numnodes <= MAX_NUMNODES
- * and that there be no holes in the numbering 0..numnodes
- * has become simply 0 <= nid <= MAX_NUMNODES.
- */
- nid = 0;
- for_each_online_node(i) {
- if (test_bit(i, (void *) nodes_with_mem)) {
- /*
- * Save original nid value for numa_slit
- * fixup and node_cpuid reassignments.
- */
- node_flip[nid] = i;
-
- if (i == nid) {
- nid++;
- continue;
- }
-
- for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
- if (p->nid == i)
- p->nid = nid;
-
- cpunid = nid;
- nid++;
- } else
- cpunid = MAX_NUMNODES;
-
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- if (node_cpuid[cpu].nid == i) {
- /*
- * For nodes not being reassigned just
- * fix the cpu's nid and reverse pxm map
- */
- if (cpunid < MAX_NUMNODES) {
- pxm = nid_to_pxm_map[i];
- pxm_to_nid_map[pxm] =
- node_cpuid[cpu].nid = cpunid;
- continue;
- }
-
- /*
- * For nodes being reassigned, find best node by
- * numa_slit information and then make a temporary
- * nid value based on current nid and num_online_nodes().
- */
- slit = 0xff;
- k = 2*num_online_nodes();
- for_each_online_node(j) {
- if (i == j)
- continue;
- else if (test_bit(j, (void *) nodes_with_mem)) {
- cslit = numa_slit[i * num_online_nodes() + j];
- if (cslit < slit) {
- k = num_online_nodes() + j;
- slit = cslit;
- }
- }
- }
-
- /* save old nid map so we can update the pxm */
- old_nid_map[cpu] = node_cpuid[cpu].nid;
- node_cpuid[cpu].nid = k;
- }
- }
-
- /*
- * Fixup temporary nid values for CPU-only nodes.
- */
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- if (node_cpuid[cpu].nid == (2*num_online_nodes())) {
- pxm = nid_to_pxm_map[old_nid_map[cpu]];
- pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = nnode - 1;
- } else {
- for (i = 0; i < nnode; i++) {
- if (node_flip[i] != (node_cpuid[cpu].nid - num_online_nodes()))
- continue;
-
- pxm = nid_to_pxm_map[old_nid_map[cpu]];
- pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = i;
- break;
- }
- }
-
- /*
- * Fix numa_slit by compressing from larger
- * nid array to reduced nid array.
- */
- for (i = 0; i < nnode; i++)
- for (j = 0; j < nnode; j++)
- numa_slit_fix[i * nnode + j] =
- numa_slit[node_flip[i] * num_online_nodes() + node_flip[j]];
-
- memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit));
-
- nodes_clear(node_online_map);
- for (i = 0; i < nnode; i++)
- node_set_online(i);
-
- return;
-}
+static nodemask_t memory_less_mask __initdata;
/*
* To prevent cache aliasing effects, align per-node structures so that they
@@ -233,44 +90,101 @@ static int __init build_node_maps(unsigned long start, unsigned long len,
}
/**
- * early_nr_phys_cpus_node - return number of physical cpus on a given node
+ * early_nr_cpus_node - return number of cpus on a given node
* @node: node to check
*
- * Count the number of physical cpus on @node. These are cpus that actually
- * exist. We can't use nr_cpus_node() yet because
+ * Count the number of cpus on @node. We can't use nr_cpus_node() yet because
* acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
- * called yet.
+ * called yet. Note that node 0 will also count all non-existent cpus.
*/
-static int early_nr_phys_cpus_node(int node)
+static int __init early_nr_cpus_node(int node)
{
int cpu, n = 0;
for (cpu = 0; cpu < NR_CPUS; cpu++)
if (node == node_cpuid[cpu].nid)
- if ((cpu == 0) || node_cpuid[cpu].phys_id)
- n++;
+ n++;
return n;
}
+/**
+ * compute_pernodesize - compute size of pernode data
+ * @node: the node id.
+ */
+static unsigned long __init compute_pernodesize(int node)
+{
+ unsigned long pernodesize = 0, cpus;
+
+ cpus = early_nr_cpus_node(node);
+ pernodesize += PERCPU_PAGE_SIZE * cpus;
+ pernodesize += node * L1_CACHE_BYTES;
+ pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
+ pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+ pernodesize = PAGE_ALIGN(pernodesize);
+ return pernodesize;
+}
/**
- * early_nr_cpus_node - return number of cpus on a given node
- * @node: node to check
+ * per_cpu_node_setup - setup per-cpu areas on each node
+ * @cpu_data: per-cpu area on this node
+ * @node: node to setup
*
- * Count the number of cpus on @node. We can't use nr_cpus_node() yet because
- * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
- * called yet. Note that node 0 will also count all non-existent cpus.
+ * Copy the static per-cpu data into the region we just set aside and then
+ * setup __per_cpu_offset for each CPU on this node. Return a pointer to
+ * the end of the area.
*/
-static int early_nr_cpus_node(int node)
+static void *per_cpu_node_setup(void *cpu_data, int node)
{
- int cpu, n = 0;
+#ifdef CONFIG_SMP
+ int cpu;
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- if (node == node_cpuid[cpu].nid)
- n++;
+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ if (node == node_cpuid[cpu].nid) {
+ memcpy(__va(cpu_data), __phys_per_cpu_start,
+ __per_cpu_end - __per_cpu_start);
+ __per_cpu_offset[cpu] = (char*)__va(cpu_data) -
+ __per_cpu_start;
+ cpu_data += PERCPU_PAGE_SIZE;
+ }
+ }
+#endif
+ return cpu_data;
+}
- return n;
+/**
+ * fill_pernode - initialize pernode data.
+ * @node: the node id.
+ * @pernode: physical address of pernode data
+ * @pernodesize: size of the pernode data
+ */
+static void __init fill_pernode(int node, unsigned long pernode,
+ unsigned long pernodesize)
+{
+ void *cpu_data;
+ int cpus = early_nr_cpus_node(node);
+ struct bootmem_data *bdp = &mem_data[node].bootmem_data;
+
+ mem_data[node].pernode_addr = pernode;
+ mem_data[node].pernode_size = pernodesize;
+ memset(__va(pernode), 0, pernodesize);
+
+ cpu_data = (void *)pernode;
+ pernode += PERCPU_PAGE_SIZE * cpus;
+ pernode += node * L1_CACHE_BYTES;
+
+ mem_data[node].pgdat = __va(pernode);
+ pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+ mem_data[node].node_data = __va(pernode);
+ pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+
+ mem_data[node].pgdat->bdata = bdp;
+ pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+ cpu_data = per_cpu_node_setup(cpu_data, node);
+
+ return;
}
/**
@@ -304,9 +218,8 @@ static int early_nr_cpus_node(int node)
static int __init find_pernode_space(unsigned long start, unsigned long len,
int node)
{
- unsigned long epfn, cpu, cpus, phys_cpus;
+ unsigned long epfn;
unsigned long pernodesize = 0, pernode, pages, mapsize;
- void *cpu_data;
struct bootmem_data *bdp = &mem_data[node].bootmem_data;
epfn = (start + len) >> PAGE_SHIFT;
@@ -329,49 +242,12 @@ static int __init find_pernode_space(unsigned long start, unsigned long len,
* Calculate total size needed, incl. what's necessary
* for good alignment and alias prevention.
*/
- cpus = early_nr_cpus_node(node);
- phys_cpus = early_nr_phys_cpus_node(node);
- pernodesize += PERCPU_PAGE_SIZE * cpus;
- pernodesize += node * L1_CACHE_BYTES;
- pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
- pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
- pernodesize = PAGE_ALIGN(pernodesize);
+ pernodesize = compute_pernodesize(node);
pernode = NODEDATA_ALIGN(start, node);
/* Is this range big enough for what we want to store here? */
- if (start + len > (pernode + pernodesize + mapsize)) {
- mem_data[node].pernode_addr = pernode;
- mem_data[node].pernode_size = pernodesize;
- memset(__va(pernode), 0, pernodesize);
-
- cpu_data = (void *)pernode;
- pernode += PERCPU_PAGE_SIZE * cpus;
- pernode += node * L1_CACHE_BYTES;
-
- mem_data[node].pgdat = __va(pernode);
- pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
- mem_data[node].node_data = __va(pernode);
- pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
-
- mem_data[node].pgdat->bdata = bdp;
- pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
- /*
- * Copy the static per-cpu data into the region we
- * just set aside and then setup __per_cpu_offset
- * for each CPU on this node.
- */
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- if (node == node_cpuid[cpu].nid) {
- memcpy(__va(cpu_data), __phys_per_cpu_start,
- __per_cpu_end - __per_cpu_start);
- __per_cpu_offset[cpu] = (char*)__va(cpu_data) -
- __per_cpu_start;
- cpu_data += PERCPU_PAGE_SIZE;
- }
- }
- }
+ if (start + len > (pernode + pernodesize + mapsize))
+ fill_pernode(node, pernode, pernodesize);
return 0;
}
@@ -411,6 +287,9 @@ static void __init reserve_pernode_space(void)
for_each_online_node(node) {
pg_data_t *pdp = mem_data[node].pgdat;
+ if (node_isset(node, memory_less_mask))
+ continue;
+
bdp = pdp->bdata;
/* First the bootmem_map itself */
@@ -436,8 +315,8 @@ static void __init reserve_pernode_space(void)
*/
static void __init initialize_pernode_data(void)
{
- int cpu, node;
pg_data_t *pgdat_list[MAX_NUMNODES];
+ int cpu, node;
for_each_online_node(node)
pgdat_list[node] = mem_data[node].pgdat;
@@ -447,12 +326,99 @@ static void __init initialize_pernode_data(void)
memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list,
sizeof(pgdat_list));
}
-
+#ifdef CONFIG_SMP
/* Set the node_data pointer for each per-cpu struct */
for (cpu = 0; cpu < NR_CPUS; cpu++) {
node = node_cpuid[cpu].nid;
per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data;
}
+#else
+ {
+ struct cpuinfo_ia64 *cpu0_cpu_info;
+ cpu = 0;
+ node = node_cpuid[cpu].nid;
+ cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start +
+ ((char *)&per_cpu__cpu_info - __per_cpu_start));
+ cpu0_cpu_info->node_data = mem_data[node].node_data;
+ }
+#endif /* CONFIG_SMP */
+}
+
+/**
+ * memory_less_node_alloc - * attempt to allocate memory on the best NUMA slit
+ * node but fall back to any other node when __alloc_bootmem_node fails
+ * for best.
+ * @nid: node id
+ * @pernodesize: size of this node's pernode data
+ * @align: alignment to use for this node's pernode data
+ */
+static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
+ unsigned long align)
+{
+ void *ptr = NULL;
+ u8 best = 0xff;
+ int bestnode = -1, node;
+
+ for_each_online_node(node) {
+ if (node_isset(node, memory_less_mask))
+ continue;
+ else if (node_distance(nid, node) < best) {
+ best = node_distance(nid, node);
+ bestnode = node;
+ }
+ }
+
+ ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat,
+ pernodesize, align, __pa(MAX_DMA_ADDRESS));
+
+ if (!ptr)
+ panic("NO memory for memory less node\n");
+ return ptr;
+}
+
+/**
+ * pgdat_insert - insert the pgdat into global pgdat_list
+ * @pgdat: the pgdat for a node.
+ */
+static void __init pgdat_insert(pg_data_t *pgdat)
+{
+ pg_data_t *prev = NULL, *next;
+
+ for_each_pgdat(next)
+ if (pgdat->node_id < next->node_id)
+ break;
+ else
+ prev = next;
+
+ if (prev) {
+ prev->pgdat_next = pgdat;
+ pgdat->pgdat_next = next;
+ } else {
+ pgdat->pgdat_next = pgdat_list;
+ pgdat_list = pgdat;
+ }
+
+ return;
+}
+
+/**
+ * memory_less_nodes - allocate and initialize CPU only nodes pernode
+ * information.
+ */
+static void __init memory_less_nodes(void)
+{
+ unsigned long pernodesize;
+ void *pernode;
+ int node;
+
+ for_each_node_mask(node, memory_less_mask) {
+ pernodesize = compute_pernodesize(node);
+ pernode = memory_less_node_alloc(node, pernodesize,
+ (node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
+ fill_pernode(node, __pa(pernode), pernodesize);
+ }
+
+ return;
}
/**
@@ -472,16 +438,19 @@ void __init find_memory(void)
node_set_online(0);
}
+ nodes_or(memory_less_mask, memory_less_mask, node_online_map);
min_low_pfn = -1;
max_low_pfn = 0;
- if (num_online_nodes() > 1)
- reassign_cpu_only_nodes();
-
/* These actually end up getting called by call_pernode_memory() */
efi_memmap_walk(filter_rsvd_memory, build_node_maps);
efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
+ for_each_online_node(node)
+ if (mem_data[node].bootmem_data.node_low_pfn) {
+ node_clear(node, memory_less_mask);
+ mem_data[node].min_pfn = ~0UL;
+ }
/*
* Initialize the boot memory maps in reverse order since that's
* what the bootmem allocator expects
@@ -492,17 +461,14 @@ void __init find_memory(void)
if (!node_online(node))
continue;
+ else if (node_isset(node, memory_less_mask))
+ continue;
bdp = &mem_data[node].bootmem_data;
pernode = mem_data[node].pernode_addr;
pernodesize = mem_data[node].pernode_size;
map = pernode + pernodesize;
- /* Sanity check... */
- if (!pernode)
- panic("pernode space for node %d "
- "could not be allocated!", node);
-
init_bootmem_node(mem_data[node].pgdat,
map>>PAGE_SHIFT,
bdp->node_boot_start>>PAGE_SHIFT,
@@ -512,6 +478,7 @@ void __init find_memory(void)
efi_memmap_walk(filter_rsvd_memory, free_node_bootmem);
reserve_pernode_space();
+ memory_less_nodes();
initialize_pernode_data();
max_pfn = max_low_pfn;
@@ -519,6 +486,7 @@ void __init find_memory(void)
find_initrd();
}
+#ifdef CONFIG_SMP
/**
* per_cpu_init - setup per-cpu variables
*
@@ -529,15 +497,15 @@ void *per_cpu_init(void)
{
int cpu;
- if (smp_processor_id() == 0) {
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- per_cpu(local_per_cpu_offset, cpu) =
- __per_cpu_offset[cpu];
- }
- }
+ if (smp_processor_id() != 0)
+ return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
}
+#endif /* CONFIG_SMP */
/**
* show_mem - give short summary of memory stats
@@ -560,14 +528,15 @@ void show_mem(void)
int shared = 0, cached = 0, reserved = 0;
printk("Node ID: %d\n", pgdat->node_id);
for(i = 0; i < pgdat->node_spanned_pages; i++) {
+ struct page *page = pgdat_page_nr(pgdat, i);
if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
continue;
- if (PageReserved(pgdat->node_mem_map+i))
+ if (PageReserved(page))
reserved++;
- else if (PageSwapCache(pgdat->node_mem_map+i))
+ else if (PageSwapCache(page))
cached++;
- else if (page_count(pgdat->node_mem_map+i))
- shared += page_count(pgdat->node_mem_map+i)-1;
+ else if (page_count(page))
+ shared += page_count(page)-1;
}
total_present += present;
total_reserved += reserved;
@@ -679,12 +648,13 @@ void __init paging_init(void)
max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- /* so min() will work in count_node_pages */
- for_each_online_node(node)
- mem_data[node].min_pfn = ~0UL;
-
efi_memmap_walk(filter_rsvd_memory, count_node_pages);
+ vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page));
+ vmem_map = (struct page *) vmalloc_end;
+ efi_memmap_walk(create_mem_map_page_table, NULL);
+ printk("Virtual mem_map starts at 0x%p\n", vmem_map);
+
for_each_online_node(node) {
memset(zones_size, 0, sizeof(zones_size));
memset(zholes_size, 0, sizeof(zholes_size));
@@ -718,15 +688,6 @@ void __init paging_init(void)
mem_data[node].num_dma_physpages);
}
- if (node == 0) {
- vmalloc_end -=
- PAGE_ALIGN(max_low_pfn * sizeof(struct page));
- vmem_map = (struct page *) vmalloc_end;
-
- efi_memmap_walk(create_mem_map_page_table, NULL);
- printk("Virtual mem_map starts at 0x%p\n", vmem_map);
- }
-
pfn_offset = mem_data[node].min_pfn;
NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset;
@@ -734,5 +695,11 @@ void __init paging_init(void)
pfn_offset, zholes_size);
}
+ /*
+ * Make memory less nodes become a member of the known nodes.
+ */
+ for_each_node_mask(node, memory_less_mask)
+ pgdat_insert(mem_data[node].pgdat);
+
zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
}
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 4174ec999dd..ff62551eb3a 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/kdebug.h>
extern void die (char *, struct pt_regs *, long);
@@ -102,6 +103,13 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
goto bad_area_no_up;
#endif
+ /*
+ * This is to handle the kprobes on user space access instructions
+ */
+ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
+ SIGSEGV) == NOTIFY_STOP)
+ return;
+
down_read(&mm->mmap_sem);
vma = find_vma_prev(mm, address, &prev_vma);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 4eb2f52b87a..65f9958db9f 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -597,7 +597,8 @@ mem_init (void)
kclist_add(&kcore_kernel, _stext, _end - _stext);
for_each_pgdat(pgdat)
- totalram_pages += free_all_bootmem_node(pgdat);
+ if (pgdat->bdata->node_bootmem_map)
+ totalram_pages += free_all_bootmem_node(pgdat);
reserved_pages = 0;
efi_memmap_walk(count_reserved_pages, &reserved_pages);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 88641e5095b..54d9ed444e4 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -33,8 +33,6 @@
#include <asm/hw_irq.h>
-static int pci_routeirq;
-
/*
* Low-level SAL-based PCI configuration access functions. Note that SAL
* calls are already serialized (via sal_lock), so we don't need another
@@ -139,24 +137,8 @@ static void acpi_map_iosapics(void)
static int __init
pci_acpi_init (void)
{
- struct pci_dev *dev = NULL;
-
- printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-
acpi_map_iosapics();
- if (pci_routeirq) {
- /*
- * PCI IRQ routing is set up by pci_enable_device(), but we
- * also do it here in case there are still broken drivers that
- * don't use pci_enable_device().
- */
- printk(KERN_INFO "PCI: Routing interrupts for all devices because \"pci=routeirq\" specified\n");
- for_each_pci_dev(dev)
- acpi_pci_irq_enable(dev);
- } else
- printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n");
-
return 0;
}
@@ -175,6 +157,7 @@ alloc_pci_controller (int seg)
memset(controller, 0, sizeof(*controller));
controller->segment = seg;
+ controller->node = -1;
return controller;
}
@@ -306,6 +289,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
unsigned int windows = 0;
struct pci_bus *pbus;
char *name;
+ int pxm;
controller = alloc_pci_controller(domain);
if (!controller)
@@ -313,10 +297,16 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
controller->acpi_handle = device->handle;
+ pxm = acpi_get_pxm(controller->acpi_handle);
+#ifdef CONFIG_NUMA
+ if (pxm >= 0)
+ controller->node = pxm_to_nid_map[pxm];
+#endif
+
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
&windows);
- controller->window = kmalloc(sizeof(*controller->window) * windows,
- GFP_KERNEL);
+ controller->window = kmalloc_node(sizeof(*controller->window) * windows,
+ GFP_KERNEL, controller->node);
if (!controller->window)
goto out2;
@@ -330,7 +320,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
&info);
- pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+ pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
if (pbus)
pcibios_setup_root_windows(pbus, controller);
@@ -391,6 +381,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
res->end = region->end + offset;
}
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+ unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+ struct resource *devr = &dev->resource[idx];
+
+ if (!dev->bus)
+ return 0;
+ for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+ struct resource *busr = dev->bus->resource[i];
+
+ if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+ continue;
+ if ((devr->start) && (devr->start >= busr->start) &&
+ (devr->end <= busr->end))
+ return 1;
+ }
+ return 0;
+}
+
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
{
struct pci_bus_region region;
@@ -404,7 +413,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
region.start = dev->resource[i].start;
region.end = dev->resource[i].end;
pcibios_bus_to_resource(dev, &dev->resource[i], &region);
- pci_claim_resource(dev, i);
+ if ((is_valid_resource(dev, i)))
+ pci_claim_resource(dev, i);
}
}
@@ -416,6 +426,10 @@ pcibios_fixup_bus (struct pci_bus *b)
{
struct pci_dev *dev;
+ if (b->self) {
+ pci_read_bridge_bases(b);
+ pcibios_fixup_device_resources(b->self);
+ }
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
@@ -436,18 +450,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
u16 cmd, old_cmd;
int idx;
struct resource *r;
+ unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
if (!dev)
return -EINVAL;
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for (idx=0; idx<6; idx++) {
+ for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
/* Only set up the desired resources. */
if (!(mask & (1 << idx)))
continue;
r = &dev->resource[idx];
+ if (!(r->flags & type_mask))
+ continue;
+ if ((idx == PCI_ROM_RESOURCE) &&
+ (!(r->flags & IORESOURCE_ROM_ENABLE)))
+ continue;
if (!r->start && r->end) {
printk(KERN_ERR
"PCI: Device %s not available because of resource collisions\n",
@@ -459,8 +479,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
if (r->flags & IORESOURCE_MEM)
cmd |= PCI_COMMAND_MEMORY;
}
- if (dev->resource[PCI_ROM_RESOURCE].start)
- cmd |= PCI_COMMAND_MEMORY;
if (cmd != old_cmd) {
printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
@@ -500,8 +518,6 @@ pcibios_align_resource (void *data, struct resource *res,
char * __init
pcibios_setup (char *str)
{
- if (!strcmp(str, "routeirq"))
- pci_routeirq = 1;
return NULL;
}
diff --git a/arch/ia64/sn/include/pci/pcibr_provider.h b/arch/ia64/sn/include/pci/pcibr_provider.h
deleted file mode 100644
index 1cd291d8bad..00000000000
--- a/arch/ia64/sn/include/pci/pcibr_provider.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-
-/* Workarounds */
-#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */
-
-#define BUSTYPE_MASK 0x1
-
-/* Macros given a pcibus structure */
-#define IS_PCIX(ps) ((ps)->pbi_bridge_mode & BUSTYPE_MASK)
-#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
- asic == PCIIO_ASIC_TYPE_TIOCP)
-#define IS_PIC_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
-
-
-/*
- * The different PCI Bridge types supported on the SGI Altix platforms
- */
-#define PCIBR_BRIDGETYPE_UNKNOWN -1
-#define PCIBR_BRIDGETYPE_PIC 2
-#define PCIBR_BRIDGETYPE_TIOCP 3
-
-/*
- * Bridge 64bit Direct Map Attributes
- */
-#define PCI64_ATTR_PREF (1ull << 59)
-#define PCI64_ATTR_PREC (1ull << 58)
-#define PCI64_ATTR_VIRTUAL (1ull << 57)
-#define PCI64_ATTR_BAR (1ull << 56)
-#define PCI64_ATTR_SWAP (1ull << 55)
-#define PCI64_ATTR_VIRTUAL1 (1ull << 54)
-
-#define PCI32_LOCAL_BASE 0
-#define PCI32_MAPPED_BASE 0x40000000
-#define PCI32_DIRECT_BASE 0x80000000
-
-#define IS_PCI32_MAPPED(x) ((uint64_t)(x) < PCI32_DIRECT_BASE && \
- (uint64_t)(x) >= PCI32_MAPPED_BASE)
-#define IS_PCI32_DIRECT(x) ((uint64_t)(x) >= PCI32_MAPPED_BASE)
-
-
-/*
- * Bridge PMU Address Transaltion Entry Attibutes
- */
-#define PCI32_ATE_V (0x1 << 0)
-#define PCI32_ATE_CO (0x1 << 1)
-#define PCI32_ATE_PREC (0x1 << 2)
-#define PCI32_ATE_PREF (0x1 << 3)
-#define PCI32_ATE_BAR (0x1 << 4)
-#define PCI32_ATE_ADDR_SHFT 12
-
-#define MINIMAL_ATES_REQUIRED(addr, size) \
- (IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1))
-
-#define MINIMAL_ATE_FLAG(addr, size) \
- (MINIMAL_ATES_REQUIRED((uint64_t)addr, size) ? 1 : 0)
-
-/* bit 29 of the pci address is the SWAP bit */
-#define ATE_SWAPSHIFT 29
-#define ATE_SWAP_ON(x) ((x) |= (1 << ATE_SWAPSHIFT))
-#define ATE_SWAP_OFF(x) ((x) &= ~(1 << ATE_SWAPSHIFT))
-
-/*
- * I/O page size
- */
-#if PAGE_SIZE < 16384
-#define IOPFNSHIFT 12 /* 4K per mapped page */
-#else
-#define IOPFNSHIFT 14 /* 16K per mapped page */
-#endif
-
-#define IOPGSIZE (1 << IOPFNSHIFT)
-#define IOPG(x) ((x) >> IOPFNSHIFT)
-#define IOPGOFF(x) ((x) & (IOPGSIZE-1))
-
-#define PCIBR_DEV_SWAP_DIR (1ull << 19)
-#define PCIBR_CTRL_PAGE_SIZE (0x1 << 21)
-
-/*
- * PMU resources.
- */
-struct ate_resource{
- uint64_t *ate;
- uint64_t num_ate;
- uint64_t lowest_free_index;
-};
-
-struct pcibus_info {
- struct pcibus_bussoft pbi_buscommon; /* common header */
- uint32_t pbi_moduleid;
- short pbi_bridge_type;
- short pbi_bridge_mode;
-
- struct ate_resource pbi_int_ate_resource;
- uint64_t pbi_int_ate_size;
-
- uint64_t pbi_dir_xbase;
- char pbi_hub_xid;
-
- uint64_t pbi_devreg[8];
- spinlock_t pbi_lock;
-
- uint32_t pbi_valid_devices;
- uint32_t pbi_enabled_devices;
-};
-
-/*
- * pcibus_info structure locking macros
- */
-inline static unsigned long
-pcibr_lock(struct pcibus_info *pcibus_info)
-{
- unsigned long flag;
- spin_lock_irqsave(&pcibus_info->pbi_lock, flag);
- return(flag);
-}
-#define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag)
-
-extern int pcibr_init_provider(void);
-extern void *pcibr_bus_fixup(struct pcibus_bussoft *);
-extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t);
-extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t);
-extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
-
-/*
- * prototypes for the bridge asic register access routines in pcibr_reg.c
- */
-extern void pcireg_control_bit_clr(struct pcibus_info *, uint64_t);
-extern void pcireg_control_bit_set(struct pcibus_info *, uint64_t);
-extern uint64_t pcireg_tflush_get(struct pcibus_info *);
-extern uint64_t pcireg_intr_status_get(struct pcibus_info *);
-extern void pcireg_intr_enable_bit_clr(struct pcibus_info *, uint64_t);
-extern void pcireg_intr_enable_bit_set(struct pcibus_info *, uint64_t);
-extern void pcireg_intr_addr_addr_set(struct pcibus_info *, int, uint64_t);
-extern void pcireg_force_intr_set(struct pcibus_info *, int);
-extern uint64_t pcireg_wrb_flush_get(struct pcibus_info *, int);
-extern void pcireg_int_ate_set(struct pcibus_info *, int, uint64_t);
-extern uint64_t * pcireg_int_ate_addr(struct pcibus_info *, int);
-extern void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info);
-extern void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info);
-extern int pcibr_ate_alloc(struct pcibus_info *, int);
-extern void pcibr_ate_free(struct pcibus_info *, int);
-extern void ate_write(struct pcibus_info *, int, int, uint64_t);
-#endif
diff --git a/arch/ia64/sn/include/pci/pic.h b/arch/ia64/sn/include/pci/pic.h
deleted file mode 100644
index fd18acecb1e..00000000000
--- a/arch/ia64/sn/include/pci/pic.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PIC_H
-#define _ASM_IA64_SN_PCI_PIC_H
-
-/*
- * PIC AS DEVICE ZERO
- * ------------------
- *
- * PIC handles PCI/X busses. PCI/X requires that the 'bridge' (i.e. PIC)
- * be designated as 'device 0'. That is a departure from earlier SGI
- * PCI bridges. Because of that we use config space 1 to access the
- * config space of the first actual PCI device on the bus.
- * Here's what the PIC manual says:
- *
- * The current PCI-X bus specification now defines that the parent
- * hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC
- * reduced the total number of devices from 8 to 4 and removed the
- * device registers and windows, now only supporting devices 0,1,2, and
- * 3. PIC did leave all 8 configuration space windows. The reason was
- * there was nothing to gain by removing them. Here in lies the problem.
- * The device numbering we do using 0 through 3 is unrelated to the device
- * numbering which PCI-X requires in configuration space. In the past we
- * correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc.
- * PCI-X requires we start a 1, not 0 and currently the PX brick
- * does associate our:
- *
- * device 0 with configuration space window 1,
- * device 1 with configuration space window 2,
- * device 2 with configuration space window 3,
- * device 3 with configuration space window 4.
- *
- * The net effect is that all config space access are off-by-one with
- * relation to other per-slot accesses on the PIC.
- * Here is a table that shows some of that:
- *
- * Internal Slot#
- * |
- * | 0 1 2 3
- * ----------|---------------------------------------
- * config | 0x21000 0x22000 0x23000 0x24000
- * |
- * even rrb | 0[0] n/a 1[0] n/a [] == implied even/odd
- * |
- * odd rrb | n/a 0[1] n/a 1[1]
- * |
- * int dev | 00 01 10 11
- * |
- * ext slot# | 1 2 3 4
- * ----------|---------------------------------------
- */
-
-#define PIC_ATE_TARGETID_SHFT 8
-#define PIC_HOST_INTR_ADDR 0x0000FFFFFFFFFFFFUL
-#define PIC_PCI64_ATTR_TARG_SHFT 60
-
-
-/*****************************************************************************
- *********************** PIC MMR structure mapping ***************************
- *****************************************************************************/
-
-/* NOTE: PIC WAR. PV#854697. PIC does not allow writes just to [31:0]
- * of a 64-bit register. When writing PIC registers, always write the
- * entire 64 bits.
- */
-
-struct pic {
-
- /* 0x000000-0x00FFFF -- Local Registers */
-
- /* 0x000000-0x000057 -- Standard Widget Configuration */
- uint64_t p_wid_id; /* 0x000000 */
- uint64_t p_wid_stat; /* 0x000008 */
- uint64_t p_wid_err_upper; /* 0x000010 */
- uint64_t p_wid_err_lower; /* 0x000018 */
- #define p_wid_err p_wid_err_lower
- uint64_t p_wid_control; /* 0x000020 */
- uint64_t p_wid_req_timeout; /* 0x000028 */
- uint64_t p_wid_int_upper; /* 0x000030 */
- uint64_t p_wid_int_lower; /* 0x000038 */
- #define p_wid_int p_wid_int_lower
- uint64_t p_wid_err_cmdword; /* 0x000040 */
- uint64_t p_wid_llp; /* 0x000048 */
- uint64_t p_wid_tflush; /* 0x000050 */
-
- /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */
- uint64_t p_wid_aux_err; /* 0x000058 */
- uint64_t p_wid_resp_upper; /* 0x000060 */
- uint64_t p_wid_resp_lower; /* 0x000068 */
- #define p_wid_resp p_wid_resp_lower
- uint64_t p_wid_tst_pin_ctrl; /* 0x000070 */
- uint64_t p_wid_addr_lkerr; /* 0x000078 */
-
- /* 0x000080-0x00008F -- PMU & MAP */
- uint64_t p_dir_map; /* 0x000080 */
- uint64_t _pad_000088; /* 0x000088 */
-
- /* 0x000090-0x00009F -- SSRAM */
- uint64_t p_map_fault; /* 0x000090 */
- uint64_t _pad_000098; /* 0x000098 */
-
- /* 0x0000A0-0x0000AF -- Arbitration */
- uint64_t p_arb; /* 0x0000A0 */
- uint64_t _pad_0000A8; /* 0x0000A8 */
-
- /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
- uint64_t p_ate_parity_err; /* 0x0000B0 */
- uint64_t _pad_0000B8; /* 0x0000B8 */
-
- /* 0x0000C0-0x0000FF -- PCI/GIO */
- uint64_t p_bus_timeout; /* 0x0000C0 */
- uint64_t p_pci_cfg; /* 0x0000C8 */
- uint64_t p_pci_err_upper; /* 0x0000D0 */
- uint64_t p_pci_err_lower; /* 0x0000D8 */
- #define p_pci_err p_pci_err_lower
- uint64_t _pad_0000E0[4]; /* 0x0000{E0..F8} */
-
- /* 0x000100-0x0001FF -- Interrupt */
- uint64_t p_int_status; /* 0x000100 */
- uint64_t p_int_enable; /* 0x000108 */
- uint64_t p_int_rst_stat; /* 0x000110 */
- uint64_t p_int_mode; /* 0x000118 */
- uint64_t p_int_device; /* 0x000120 */
- uint64_t p_int_host_err; /* 0x000128 */
- uint64_t p_int_addr[8]; /* 0x0001{30,,,68} */
- uint64_t p_err_int_view; /* 0x000170 */
- uint64_t p_mult_int; /* 0x000178 */
- uint64_t p_force_always[8]; /* 0x0001{80,,,B8} */
- uint64_t p_force_pin[8]; /* 0x0001{C0,,,F8} */
-
- /* 0x000200-0x000298 -- Device */
- uint64_t p_device[4]; /* 0x0002{00,,,18} */
- uint64_t _pad_000220[4]; /* 0x0002{20,,,38} */
- uint64_t p_wr_req_buf[4]; /* 0x0002{40,,,58} */
- uint64_t _pad_000260[4]; /* 0x0002{60,,,78} */
- uint64_t p_rrb_map[2]; /* 0x0002{80,,,88} */
- #define p_even_resp p_rrb_map[0] /* 0x000280 */
- #define p_odd_resp p_rrb_map[1] /* 0x000288 */
- uint64_t p_resp_status; /* 0x000290 */
- uint64_t p_resp_clear; /* 0x000298 */
-
- uint64_t _pad_0002A0[12]; /* 0x0002{A0..F8} */
-
- /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
- struct {
- uint64_t upper; /* 0x0003{00,,,F0} */
- uint64_t lower; /* 0x0003{08,,,F8} */
- } p_buf_addr_match[16];
-
- /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
- struct {
- uint64_t flush_w_touch; /* 0x000{400,,,5C0} */
- uint64_t flush_wo_touch; /* 0x000{408,,,5C8} */
- uint64_t inflight; /* 0x000{410,,,5D0} */
- uint64_t prefetch; /* 0x000{418,,,5D8} */
- uint64_t total_pci_retry; /* 0x000{420,,,5E0} */
- uint64_t max_pci_retry; /* 0x000{428,,,5E8} */
- uint64_t max_latency; /* 0x000{430,,,5F0} */
- uint64_t clear_all; /* 0x000{438,,,5F8} */
- } p_buf_count[8];
-
-
- /* 0x000600-0x0009FF -- PCI/X registers */
- uint64_t p_pcix_bus_err_addr; /* 0x000600 */
- uint64_t p_pcix_bus_err_attr; /* 0x000608 */
- uint64_t p_pcix_bus_err_data; /* 0x000610 */
- uint64_t p_pcix_pio_split_addr; /* 0x000618 */
- uint64_t p_pcix_pio_split_attr; /* 0x000620 */
- uint64_t p_pcix_dma_req_err_attr; /* 0x000628 */
- uint64_t p_pcix_dma_req_err_addr; /* 0x000630 */
- uint64_t p_pcix_timeout; /* 0x000638 */
-
- uint64_t _pad_000640[120]; /* 0x000{640,,,9F8} */
-
- /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
- struct {
- uint64_t p_buf_addr; /* 0x000{A00,,,AF0} */
- uint64_t p_buf_attr; /* 0X000{A08,,,AF8} */
- } p_pcix_read_buf_64[16];
-
- struct {
- uint64_t p_buf_addr; /* 0x000{B00,,,BE0} */
- uint64_t p_buf_attr; /* 0x000{B08,,,BE8} */
- uint64_t p_buf_valid; /* 0x000{B10,,,BF0} */
- uint64_t __pad1; /* 0x000{B18,,,BF8} */
- } p_pcix_write_buf_64[8];
-
- /* End of Local Registers -- Start of Address Map space */
-
- char _pad_000c00[0x010000 - 0x000c00];
-
- /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */
- uint64_t p_int_ate_ram[1024]; /* 0x010000-0x011fff */
-
- /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */
- uint64_t p_int_ate_ram_mp[1024]; /* 0x012000-0x013fff */
-
- char _pad_014000[0x18000 - 0x014000];
-
- /* 0x18000-0x197F8 -- PIC Write Request Ram */
- uint64_t p_wr_req_lower[256]; /* 0x18000 - 0x187F8 */
- uint64_t p_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */
- uint64_t p_wr_req_parity[256]; /* 0x19000 - 0x197F8 */
-
- char _pad_019800[0x20000 - 0x019800];
-
- /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */
- union {
- uint8_t c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */
- uint16_t s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */
- uint32_t l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */
- uint64_t d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */
- union {
- uint8_t c[0x100 / 1];
- uint16_t s[0x100 / 2];
- uint32_t l[0x100 / 4];
- uint64_t d[0x100 / 8];
- } f[8];
- } p_type0_cfg_dev[8]; /* 0x02{0000,,,7FFF} */
-
- /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
- union {
- uint8_t c[0x1000 / 1]; /* 0x028000-0x029000 */
- uint16_t s[0x1000 / 2]; /* 0x028000-0x029000 */
- uint32_t l[0x1000 / 4]; /* 0x028000-0x029000 */
- uint64_t d[0x1000 / 8]; /* 0x028000-0x029000 */
- union {
- uint8_t c[0x100 / 1];
- uint16_t s[0x100 / 2];
- uint32_t l[0x100 / 4];
- uint64_t d[0x100 / 8];
- } f[8];
- } p_type1_cfg; /* 0x028000-0x029000 */
-
- char _pad_029000[0x030000-0x029000];
-
- /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
- union {
- uint8_t c[8 / 1];
- uint16_t s[8 / 2];
- uint32_t l[8 / 4];
- uint64_t d[8 / 8];
- } p_pci_iack; /* 0x030000-0x030007 */
-
- char _pad_030007[0x040000-0x030008];
-
- /* 0x040000-0x030007 -- PCIX Special Cycle */
- union {
- uint8_t c[8 / 1];
- uint16_t s[8 / 2];
- uint32_t l[8 / 4];
- uint64_t d[8 / 8];
- } p_pcix_cycle; /* 0x040000-0x040007 */
-};
-
-#endif /* _ASM_IA64_SN_PCI_PIC_H */
diff --git a/arch/ia64/sn/include/pci/tiocp.h b/arch/ia64/sn/include/pci/tiocp.h
deleted file mode 100644
index f07c83b2bf6..00000000000
--- a/arch/ia64/sn/include/pci/tiocp.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_TIOCP_H
-#define _ASM_IA64_SN_PCI_TIOCP_H
-
-#define TIOCP_HOST_INTR_ADDR 0x003FFFFFFFFFFFFFUL
-#define TIOCP_PCI64_CMDTYPE_MEM (0x1ull << 60)
-
-
-/*****************************************************************************
- *********************** TIOCP MMR structure mapping ***************************
- *****************************************************************************/
-
-struct tiocp{
-
- /* 0x000000-0x00FFFF -- Local Registers */
-
- /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */
- uint64_t cp_id; /* 0x000000 */
- uint64_t cp_stat; /* 0x000008 */
- uint64_t cp_err_upper; /* 0x000010 */
- uint64_t cp_err_lower; /* 0x000018 */
- #define cp_err cp_err_lower
- uint64_t cp_control; /* 0x000020 */
- uint64_t cp_req_timeout; /* 0x000028 */
- uint64_t cp_intr_upper; /* 0x000030 */
- uint64_t cp_intr_lower; /* 0x000038 */
- #define cp_intr cp_intr_lower
- uint64_t cp_err_cmdword; /* 0x000040 */
- uint64_t _pad_000048; /* 0x000048 */
- uint64_t cp_tflush; /* 0x000050 */
-
- /* 0x000058-0x00007F -- Bridge-specific Configuration */
- uint64_t cp_aux_err; /* 0x000058 */
- uint64_t cp_resp_upper; /* 0x000060 */
- uint64_t cp_resp_lower; /* 0x000068 */
- #define cp_resp cp_resp_lower
- uint64_t cp_tst_pin_ctrl; /* 0x000070 */
- uint64_t cp_addr_lkerr; /* 0x000078 */
-
- /* 0x000080-0x00008F -- PMU & MAP */
- uint64_t cp_dir_map; /* 0x000080 */
- uint64_t _pad_000088; /* 0x000088 */
-
- /* 0x000090-0x00009F -- SSRAM */
- uint64_t cp_map_fault; /* 0x000090 */
- uint64_t _pad_000098; /* 0x000098 */
-
- /* 0x0000A0-0x0000AF -- Arbitration */
- uint64_t cp_arb; /* 0x0000A0 */
- uint64_t _pad_0000A8; /* 0x0000A8 */
-
- /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
- uint64_t cp_ate_parity_err; /* 0x0000B0 */
- uint64_t _pad_0000B8; /* 0x0000B8 */
-
- /* 0x0000C0-0x0000FF -- PCI/GIO */
- uint64_t cp_bus_timeout; /* 0x0000C0 */
- uint64_t cp_pci_cfg; /* 0x0000C8 */
- uint64_t cp_pci_err_upper; /* 0x0000D0 */
- uint64_t cp_pci_err_lower; /* 0x0000D8 */
- #define cp_pci_err cp_pci_err_lower
- uint64_t _pad_0000E0[4]; /* 0x0000{E0..F8} */
-
- /* 0x000100-0x0001FF -- Interrupt */
- uint64_t cp_int_status; /* 0x000100 */
- uint64_t cp_int_enable; /* 0x000108 */
- uint64_t cp_int_rst_stat; /* 0x000110 */
- uint64_t cp_int_mode; /* 0x000118 */
- uint64_t cp_int_device; /* 0x000120 */
- uint64_t cp_int_host_err; /* 0x000128 */
- uint64_t cp_int_addr[8]; /* 0x0001{30,,,68} */
- uint64_t cp_err_int_view; /* 0x000170 */
- uint64_t cp_mult_int; /* 0x000178 */
- uint64_t cp_force_always[8]; /* 0x0001{80,,,B8} */
- uint64_t cp_force_pin[8]; /* 0x0001{C0,,,F8} */
-
- /* 0x000200-0x000298 -- Device */
- uint64_t cp_device[4]; /* 0x0002{00,,,18} */
- uint64_t _pad_000220[4]; /* 0x0002{20,,,38} */
- uint64_t cp_wr_req_buf[4]; /* 0x0002{40,,,58} */
- uint64_t _pad_000260[4]; /* 0x0002{60,,,78} */
- uint64_t cp_rrb_map[2]; /* 0x0002{80,,,88} */
- #define cp_even_resp cp_rrb_map[0] /* 0x000280 */
- #define cp_odd_resp cp_rrb_map[1] /* 0x000288 */
- uint64_t cp_resp_status; /* 0x000290 */
- uint64_t cp_resp_clear; /* 0x000298 */
-
- uint64_t _pad_0002A0[12]; /* 0x0002{A0..F8} */
-
- /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
- struct {
- uint64_t upper; /* 0x0003{00,,,F0} */
- uint64_t lower; /* 0x0003{08,,,F8} */
- } cp_buf_addr_match[16];
-
- /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
- struct {
- uint64_t flush_w_touch; /* 0x000{400,,,5C0} */
- uint64_t flush_wo_touch; /* 0x000{408,,,5C8} */
- uint64_t inflight; /* 0x000{410,,,5D0} */
- uint64_t prefetch; /* 0x000{418,,,5D8} */
- uint64_t total_pci_retry; /* 0x000{420,,,5E0} */
- uint64_t max_pci_retry; /* 0x000{428,,,5E8} */
- uint64_t max_latency; /* 0x000{430,,,5F0} */
- uint64_t clear_all; /* 0x000{438,,,5F8} */
- } cp_buf_count[8];
-
-
- /* 0x000600-0x0009FF -- PCI/X registers */
- uint64_t cp_pcix_bus_err_addr; /* 0x000600 */
- uint64_t cp_pcix_bus_err_attr; /* 0x000608 */
- uint64_t cp_pcix_bus_err_data; /* 0x000610 */
- uint64_t cp_pcix_pio_split_addr; /* 0x000618 */
- uint64_t cp_pcix_pio_split_attr; /* 0x000620 */
- uint64_t cp_pcix_dma_req_err_attr; /* 0x000628 */
- uint64_t cp_pcix_dma_req_err_addr; /* 0x000630 */
- uint64_t cp_pcix_timeout; /* 0x000638 */
-
- uint64_t _pad_000640[24]; /* 0x000{640,,,6F8} */
-
- /* 0x000700-0x000737 -- Debug Registers */
- uint64_t cp_ct_debug_ctl; /* 0x000700 */
- uint64_t cp_br_debug_ctl; /* 0x000708 */
- uint64_t cp_mux3_debug_ctl; /* 0x000710 */
- uint64_t cp_mux4_debug_ctl; /* 0x000718 */
- uint64_t cp_mux5_debug_ctl; /* 0x000720 */
- uint64_t cp_mux6_debug_ctl; /* 0x000728 */
- uint64_t cp_mux7_debug_ctl; /* 0x000730 */
-
- uint64_t _pad_000738[89]; /* 0x000{738,,,9F8} */
-
- /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
- struct {
- uint64_t cp_buf_addr; /* 0x000{A00,,,AF0} */
- uint64_t cp_buf_attr; /* 0X000{A08,,,AF8} */
- } cp_pcix_read_buf_64[16];
-
- struct {
- uint64_t cp_buf_addr; /* 0x000{B00,,,BE0} */
- uint64_t cp_buf_attr; /* 0x000{B08,,,BE8} */
- uint64_t cp_buf_valid; /* 0x000{B10,,,BF0} */
- uint64_t __pad1; /* 0x000{B18,,,BF8} */
- } cp_pcix_write_buf_64[8];
-
- /* End of Local Registers -- Start of Address Map space */
-
- char _pad_000c00[0x010000 - 0x000c00];
-
- /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */
- uint64_t cp_int_ate_ram[1024]; /* 0x010000-0x011FF8 */
-
- char _pad_012000[0x14000 - 0x012000];
-
- /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */
- uint64_t cp_int_ate_ram_mp[1024]; /* 0x014000-0x015FF8 */
-
- char _pad_016000[0x18000 - 0x016000];
-
- /* 0x18000-0x197F8 -- TIOCP Write Request Ram */
- uint64_t cp_wr_req_lower[256]; /* 0x18000 - 0x187F8 */
- uint64_t cp_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */
- uint64_t cp_wr_req_parity[256]; /* 0x19000 - 0x197F8 */
-
- char _pad_019800[0x1C000 - 0x019800];
-
- /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */
- uint64_t cp_rd_resp_lower[512]; /* 0x1C000 - 0x1CFF8 */
- uint64_t cp_rd_resp_upper[512]; /* 0x1D000 - 0x1DFF8 */
- uint64_t cp_rd_resp_parity[512]; /* 0x1E000 - 0x1EFF8 */
-
- char _pad_01F000[0x20000 - 0x01F000];
-
- /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used) */
- char _pad_020000[0x021000 - 0x20000];
-
- /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */
- union {
- uint8_t c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */
- uint16_t s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */
- uint32_t l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */
- uint64_t d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */
- union {
- uint8_t c[0x100 / 1];
- uint16_t s[0x100 / 2];
- uint32_t l[0x100 / 4];
- uint64_t d[0x100 / 8];
- } f[8];
- } cp_type0_cfg_dev[7]; /* 0x02{1000,,,7FFF} */
-
- /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
- union {
- uint8_t c[0x1000 / 1]; /* 0x028000-0x029000 */
- uint16_t s[0x1000 / 2]; /* 0x028000-0x029000 */
- uint32_t l[0x1000 / 4]; /* 0x028000-0x029000 */
- uint64_t d[0x1000 / 8]; /* 0x028000-0x029000 */
- union {
- uint8_t c[0x100 / 1];
- uint16_t s[0x100 / 2];
- uint32_t l[0x100 / 4];
- uint64_t d[0x100 / 8];
- } f[8];
- } cp_type1_cfg; /* 0x028000-0x029000 */
-
- char _pad_029000[0x030000-0x029000];
-
- /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
- union {
- uint8_t c[8 / 1];
- uint16_t s[8 / 2];
- uint32_t l[8 / 4];
- uint64_t d[8 / 8];
- } cp_pci_iack; /* 0x030000-0x030007 */
-
- char _pad_030007[0x040000-0x030008];
-
- /* 0x040000-0x040007 -- PCIX Special Cycle */
- union {
- uint8_t c[8 / 1];
- uint16_t s[8 / 2];
- uint32_t l[8 / 4];
- uint64_t d[8 / 8];
- } cp_pcix_cycle; /* 0x040000-0x040007 */
-
- char _pad_040007[0x200000-0x040008];
-
- /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */
- union {
- uint8_t c[0x100000 / 1];
- uint16_t s[0x100000 / 2];
- uint32_t l[0x100000 / 4];
- uint64_t d[0x100000 / 8];
- } cp_devio_raw[6]; /* 0x200000-0x7FFFFF */
-
- #define cp_devio(n) cp_devio_raw[((n)<2)?(n*2):(n+2)]
-
- char _pad_800000[0xA00000-0x800000];
-
- /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush */
- union {
- uint8_t c[0x100000 / 1];
- uint16_t s[0x100000 / 2];
- uint32_t l[0x100000 / 4];
- uint64_t d[0x100000 / 8];
- } cp_devio_raw_flush[6]; /* 0xA00000-0xBFFFFF */
-
- #define cp_devio_flush(n) cp_devio_raw_flush[((n)<2)?(n*2):(n+2)]
-
-};
-
-#endif /* _ASM_IA64_SN_PCI_TIOCP_H */
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
index 868e7ecae84..580a1c0403a 100644
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -8,6 +8,8 @@
#ifndef _ASM_IA64_SN_XTALK_HUBDEV_H
#define _ASM_IA64_SN_XTALK_HUBDEV_H
+#include "xtalk/xwidgetdev.h"
+
#define HUB_WIDGET_ID_MAX 0xf
#define DEV_PER_WIDGET (2*2*8)
#define IIO_ITTE_WIDGET_BITS 4 /* size of widget field */
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 9e07f5463f2..a6649baf629 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -9,21 +9,28 @@
#include <linux/bootmem.h>
#include <linux/nodemask.h>
#include <asm/sn/types.h>
-#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
-#include "xtalk/xwidgetdev.h"
#include <asm/sn/geo.h>
-#include "xtalk/hubdev.h"
#include <asm/sn/io.h>
+#include <asm/sn/pcibr_provider.h>
+#include <asm/sn/pcibus_provider_defs.h>
+#include <asm/sn/pcidev.h>
#include <asm/sn/simulator.h>
+#include <asm/sn/sn_sal.h>
#include <asm/sn/tioca_provider.h>
+#include "xtalk/hubdev.h"
+#include "xtalk/xwidgetdev.h"
-char master_baseio_wid;
nasid_t master_nasid = INVALID_NASID; /* Partition Master */
+static struct list_head sn_sysdata_list;
+
+/* sysdata list struct */
+struct sysdata_el {
+ struct list_head entry;
+ void *sysdata;
+};
+
struct slab_info {
struct hubdev_info hubdev;
};
@@ -54,7 +61,7 @@ sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
}
static void *
-sn_default_pci_bus_fixup(struct pcibus_bussoft *soft)
+sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
{
return NULL;
}
@@ -138,23 +145,6 @@ sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev,
}
/*
- * sn_alloc_pci_sysdata() - This routine allocates a pci controller
- * which is expected as the pci_dev and pci_bus sysdata by the Linux
- * PCI infrastructure.
- */
-static inline struct pci_controller *sn_alloc_pci_sysdata(void)
-{
- struct pci_controller *pci_sysdata;
-
- pci_sysdata = kmalloc(sizeof(*pci_sysdata), GFP_KERNEL);
- if (!pci_sysdata)
- BUG();
-
- memset(pci_sysdata, 0, sizeof(*pci_sysdata));
- return pci_sysdata;
-}
-
-/*
* sn_fixup_ionodes() - This routine initializes the HUB data strcuture for
* each node in the system.
*/
@@ -221,22 +211,34 @@ static void sn_fixup_ionodes(void)
}
+void sn_pci_unfixup_slot(struct pci_dev *dev)
+{
+ struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;
+
+ sn_irq_unfixup(dev);
+ pci_dev_put(host_pci_dev);
+ pci_dev_put(dev);
+}
+
/*
* sn_pci_fixup_slot() - This routine sets up a slot's resources
* consistent with the Linux PCI abstraction layer. Resources acquired
* from our PCI provider include PIO maps to BAR space and interrupt
* objects.
*/
-static void sn_pci_fixup_slot(struct pci_dev *dev)
+void sn_pci_fixup_slot(struct pci_dev *dev)
{
int idx;
int segment = 0;
- uint64_t size;
- struct sn_irq_info *sn_irq_info;
- struct pci_dev *host_pci_dev;
int status = 0;
struct pcibus_bussoft *bs;
+ struct pci_bus *host_pci_bus;
+ struct pci_dev *host_pci_dev;
+ struct sn_irq_info *sn_irq_info;
+ unsigned long size;
+ unsigned int bus_no, devfn;
+ pci_dev_get(dev); /* for the sysdata pointer */
dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
if (SN_PCIDEV_INFO(dev) <= 0)
BUG(); /* Cannot afford to run out of memory */
@@ -253,7 +255,7 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
(u64) __pa(SN_PCIDEV_INFO(dev)),
(u64) __pa(sn_irq_info));
if (status)
- BUG(); /* Cannot get platform pci device information information */
+ BUG(); /* Cannot get platform pci device information */
/* Copy over PIO Mapped Addresses */
for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
@@ -275,15 +277,21 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
dev->resource[idx].parent = &iomem_resource;
}
- /* set up host bus linkages */
- bs = SN_PCIBUS_BUSSOFT(dev->bus);
- host_pci_dev =
- pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32,
- SN_PCIDEV_INFO(dev)->
- pdi_slot_host_handle & 0xffffffff);
+ /*
+ * Using the PROMs values for the PCI host bus, get the Linux
+ * PCI host_pci_dev struct and set up host bus linkages
+ */
+
+ bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32;
+ devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff;
+ host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no);
+ host_pci_dev = pci_get_slot(host_pci_bus, devfn);
+
+ SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev;
SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info =
- SN_PCIDEV_INFO(host_pci_dev);
+ SN_PCIDEV_INFO(host_pci_dev);
SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
+ bs = SN_PCIBUS_BUSSOFT(dev->bus);
SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs;
if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
@@ -297,6 +305,9 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info;
dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq;
sn_irq_fixup(dev, sn_irq_info);
+ } else {
+ SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL;
+ kfree(sn_irq_info);
}
}
@@ -304,55 +315,57 @@ static void sn_pci_fixup_slot(struct pci_dev *dev)
* sn_pci_controller_fixup() - This routine sets up a bus's resources
* consistent with the Linux PCI abstraction layer.
*/
-static void sn_pci_controller_fixup(int segment, int busnum)
+void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
{
int status = 0;
int nasid, cnode;
- struct pci_bus *bus;
struct pci_controller *controller;
struct pcibus_bussoft *prom_bussoft_ptr;
struct hubdev_info *hubdev_info;
void *provider_soft;
struct sn_pcibus_provider *provider;
- status =
- sal_get_pcibus_info((u64) segment, (u64) busnum,
- (u64) ia64_tpa(&prom_bussoft_ptr));
- if (status > 0) {
- return; /* bus # does not exist */
- }
-
+ status = sal_get_pcibus_info((u64) segment, (u64) busnum,
+ (u64) ia64_tpa(&prom_bussoft_ptr));
+ if (status > 0)
+ return; /*bus # does not exist */
prom_bussoft_ptr = __va(prom_bussoft_ptr);
- controller = sn_alloc_pci_sysdata();
- /* controller non-zero is BUG'd in sn_alloc_pci_sysdata */
- bus = pci_scan_bus(busnum, &pci_root_ops, controller);
+ controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
+ if (!controller)
+ BUG();
+
if (bus == NULL) {
- return; /* error, or bus already scanned */
+ bus = pci_scan_bus(busnum, &pci_root_ops, controller);
+ if (bus == NULL)
+ return; /* error, or bus already scanned */
+ bus->sysdata = NULL;
}
+ if (bus->sysdata)
+ goto error_return; /* sysdata already alloc'd */
+
/*
* Per-provider fixup. Copies the contents from prom to local
* area and links SN_PCIBUS_BUSSOFT().
*/
- if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
+ if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES)
return; /* unsupported asic type */
- }
+
+ if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB)
+ goto error_return; /* no further fixup necessary */
provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
- if (provider == NULL) {
+ if (provider == NULL)
return; /* no provider registerd for this asic */
- }
provider_soft = NULL;
- if (provider->bus_fixup) {
- provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr);
- }
+ if (provider->bus_fixup)
+ provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller);
- if (provider_soft == NULL) {
+ if (provider_soft == NULL)
return; /* fixup failed or not applicable */
- }
/*
* Generic bus fixup goes here. Don't reference prom_bussoft_ptr
@@ -361,12 +374,63 @@ static void sn_pci_controller_fixup(int segment, int busnum)
bus->sysdata = controller;
PCI_CONTROLLER(bus)->platform_data = provider_soft;
-
nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
cnode = nasid_to_cnodeid(nasid);
hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
&(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);
+
+ /*
+ * If the node information we obtained during the fixup phase is invalid
+ * then set controller->node to -1 (undetermined)
+ */
+ if (controller->node >= num_online_nodes()) {
+ struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
+
+ printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu"
+ "L_IO=%lx L_MEM=%lx BASE=%lx\n",
+ b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
+ b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
+ printk(KERN_WARNING "on node %d but only %d nodes online."
+ "Association set to undetermined.\n",
+ controller->node, num_online_nodes());
+ controller->node = -1;
+ }
+ return;
+
+error_return:
+
+ kfree(controller);
+ return;
+}
+
+void sn_bus_store_sysdata(struct pci_dev *dev)
+{
+ struct sysdata_el *element;
+
+ element = kcalloc(1, sizeof(struct sysdata_el), GFP_KERNEL);
+ if (!element) {
+ dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
+ return;
+ }
+ element->sysdata = dev->sysdata;
+ list_add(&element->entry, &sn_sysdata_list);
+}
+
+void sn_bus_free_sysdata(void)
+{
+ struct sysdata_el *element;
+ struct list_head *list;
+
+sn_sysdata_free_start:
+ list_for_each(list, &sn_sysdata_list) {
+ element = list_entry(list, struct sysdata_el, entry);
+ list_del(&element->entry);
+ kfree(element->sysdata);
+ kfree(element);
+ goto sn_sysdata_free_start;
+ }
+ return;
}
/*
@@ -384,7 +448,7 @@ static int __init sn_pci_init(void)
extern void register_sn_procfs(void);
#endif
- if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR())
+ if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
return 0;
/*
@@ -403,20 +467,17 @@ static int __init sn_pci_init(void)
*/
ia64_max_iommu_merge_mask = ~PAGE_MASK;
sn_fixup_ionodes();
- sn_irq = kmalloc(sizeof(struct sn_irq_info *) * NR_IRQS, GFP_KERNEL);
- if (sn_irq <= 0)
- BUG(); /* Canno afford to run out of memory. */
- memset(sn_irq, 0, sizeof(struct sn_irq_info *) * NR_IRQS);
-
+ sn_irq_lh_init();
+ INIT_LIST_HEAD(&sn_sysdata_list);
sn_init_cpei_timer();
#ifdef CONFIG_PROC_FS
register_sn_procfs();
#endif
- for (i = 0; i < PCI_BUSES_TO_SCAN; i++) {
- sn_pci_controller_fixup(0, i);
- }
+ /* busses are not known yet ... */
+ for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
+ sn_pci_controller_fixup(0, i, NULL);
/*
* Generic Linux PCI Layer has created the pci_bus and pci_dev
@@ -425,9 +486,8 @@ static int __init sn_pci_init(void)
*/
while ((pci_dev =
- pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
+ pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL)
sn_pci_fixup_slot(pci_dev);
- }
sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */
@@ -469,3 +529,8 @@ cnodeid_get_geoid(cnodeid_t cnode)
}
subsys_initcall(sn_pci_init);
+EXPORT_SYMBOL(sn_pci_fixup_slot);
+EXPORT_SYMBOL(sn_pci_unfixup_slot);
+EXPORT_SYMBOL(sn_pci_controller_fixup);
+EXPORT_SYMBOL(sn_bus_store_sysdata);
+EXPORT_SYMBOL(sn_bus_free_sysdata);
diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
index fec6d8b8237..7ce3cdad627 100644
--- a/arch/ia64/sn/kernel/iomv.c
+++ b/arch/ia64/sn/kernel/iomv.c
@@ -9,12 +9,16 @@
#include <linux/module.h>
#include <asm/io.h>
#include <asm/delay.h>
+#include <asm/vga.h>
#include <asm/sn/nodepda.h>
#include <asm/sn/simulator.h>
#include <asm/sn/pda.h>
#include <asm/sn/sn_cpuid.h>
#include <asm/sn/shub_mmr.h>
+#define IS_LEGACY_VGA_IOPORT(p) \
+ (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df))
+
/**
* sn_io_addr - convert an in/out port to an i/o address
* @port: port to convert
@@ -26,6 +30,8 @@
void *sn_io_addr(unsigned long port)
{
if (!IS_RUNNING_ON_SIMULATOR()) {
+ if (IS_LEGACY_VGA_IOPORT(port))
+ port += vga_console_iobase;
/* On sn2, legacy I/O ports don't point at anything */
if (port < (64 * 1024))
return NULL;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 0f4e8138658..84d276a14ec 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -9,13 +9,13 @@
*/
#include <linux/irq.h>
-#include <asm/sn/intr.h>
+#include <linux/spinlock.h>
#include <asm/sn/addrs.h>
#include <asm/sn/arch.h>
-#include "xtalk/xwidgetdev.h"
+#include <asm/sn/intr.h>
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
#include <asm/sn/shub_mmr.h>
#include <asm/sn/sn_sal.h>
@@ -25,7 +25,8 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
extern int sn_force_interrupt_flag;
extern int sn_ioif_inited;
-struct sn_irq_info **sn_irq;
+static struct list_head **sn_irq_lh;
+static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget,
u64 sn_irq_info,
@@ -101,7 +102,7 @@ static void sn_end_irq(unsigned int irq)
nasid = get_nasid();
event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR
(nasid, SH_EVENT_OCCURRED));
- /* If the UART bit is set here, we may have received an
+ /* If the UART bit is set here, we may have received an
* interrupt from the UART that the driver missed. To
* make sure, we IPI ourselves to force us to look again.
*/
@@ -115,82 +116,84 @@ static void sn_end_irq(unsigned int irq)
force_interrupt(irq);
}
+static void sn_irq_info_free(struct rcu_head *head);
+
static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
{
- struct sn_irq_info *sn_irq_info = sn_irq[irq];
- struct sn_irq_info *tmp_sn_irq_info;
+ struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
int cpuid, cpuphys;
- nasid_t t_nasid; /* nasid to target */
- int t_slice; /* slice to target */
-
- /* allocate a temp sn_irq_info struct to get new target info */
- tmp_sn_irq_info = kmalloc(sizeof(*tmp_sn_irq_info), GFP_KERNEL);
- if (!tmp_sn_irq_info)
- return;
cpuid = first_cpu(mask);
cpuphys = cpu_physical_id(cpuid);
- t_nasid = cpuid_to_nasid(cpuid);
- t_slice = cpuid_to_slice(cpuid);
- while (sn_irq_info) {
- int status;
- int local_widget;
- uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge;
- nasid_t local_nasid = NASID_GET(bridge);
+ list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
+ sn_irq_lh[irq], list) {
+ uint64_t bridge;
+ int local_widget, status;
+ nasid_t local_nasid;
+ struct sn_irq_info *new_irq_info;
+
+ new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
+ if (new_irq_info == NULL)
+ break;
+ memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
+
+ bridge = (uint64_t) new_irq_info->irq_bridge;
+ if (!bridge) {
+ kfree(new_irq_info);
+ break; /* irq is not a device interrupt */
+ }
- if (!bridge)
- break; /* irq is not a device interrupt */
+ local_nasid = NASID_GET(bridge);
if (local_nasid & 1)
local_widget = TIO_SWIN_WIDGETNUM(bridge);
else
local_widget = SWIN_WIDGETNUM(bridge);
- /* Free the old PROM sn_irq_info structure */
- sn_intr_free(local_nasid, local_widget, sn_irq_info);
+ /* Free the old PROM new_irq_info structure */
+ sn_intr_free(local_nasid, local_widget, new_irq_info);
+ /* Update kernels new_irq_info with new target info */
+ unregister_intr_pda(new_irq_info);
- /* allocate a new PROM sn_irq_info struct */
+ /* allocate a new PROM new_irq_info struct */
status = sn_intr_alloc(local_nasid, local_widget,
- __pa(tmp_sn_irq_info), irq, t_nasid,
- t_slice);
-
- if (status == 0) {
- /* Update kernels sn_irq_info with new target info */
- unregister_intr_pda(sn_irq_info);
- sn_irq_info->irq_cpuid = cpuid;
- sn_irq_info->irq_nasid = t_nasid;
- sn_irq_info->irq_slice = t_slice;
- sn_irq_info->irq_xtalkaddr =
- tmp_sn_irq_info->irq_xtalkaddr;
- sn_irq_info->irq_cookie = tmp_sn_irq_info->irq_cookie;
- register_intr_pda(sn_irq_info);
-
- if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type)) {
- pcibr_change_devices_irq(sn_irq_info);
- }
+ __pa(new_irq_info), irq,
+ cpuid_to_nasid(cpuid),
+ cpuid_to_slice(cpuid));
+
+ /* SAL call failed */
+ if (status) {
+ kfree(new_irq_info);
+ break;
+ }
+
+ new_irq_info->irq_cpuid = cpuid;
+ register_intr_pda(new_irq_info);
+
+ if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type))
+ pcibr_change_devices_irq(new_irq_info);
- sn_irq_info = sn_irq_info->irq_next;
+ spin_lock(&sn_irq_info_lock);
+ list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
+ spin_unlock(&sn_irq_info_lock);
+ call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
#ifdef CONFIG_SMP
- set_irq_affinity_info((irq & 0xff), cpuphys, 0);
+ set_irq_affinity_info((irq & 0xff), cpuphys, 0);
#endif
- } else {
- break; /* snp_affinity failed the intr_alloc */
- }
}
- kfree(tmp_sn_irq_info);
}
struct hw_interrupt_type irq_type_sn = {
- "SN hub",
- sn_startup_irq,
- sn_shutdown_irq,
- sn_enable_irq,
- sn_disable_irq,
- sn_ack_irq,
- sn_end_irq,
- sn_set_affinity_irq
+ .typename = "SN hub",
+ .startup = sn_startup_irq,
+ .shutdown = sn_shutdown_irq,
+ .enable = sn_enable_irq,
+ .disable = sn_disable_irq,
+ .ack = sn_ack_irq,
+ .end = sn_end_irq,
+ .set_affinity = sn_set_affinity_irq
};
unsigned int sn_local_vector_to_irq(u8 vector)
@@ -231,19 +234,18 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
struct sn_irq_info *tmp_irq_info;
int i, foundmatch;
+ rcu_read_lock();
if (pdacpu(cpu)->sn_last_irq == irq) {
foundmatch = 0;
- for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--) {
- tmp_irq_info = sn_irq[i];
- while (tmp_irq_info) {
+ for (i = pdacpu(cpu)->sn_last_irq - 1;
+ i && !foundmatch; i--) {
+ list_for_each_entry_rcu(tmp_irq_info,
+ sn_irq_lh[i],
+ list) {
if (tmp_irq_info->irq_cpuid == cpu) {
- foundmatch++;
+ foundmatch = 1;
break;
}
- tmp_irq_info = tmp_irq_info->irq_next;
- }
- if (foundmatch) {
- break;
}
}
pdacpu(cpu)->sn_last_irq = i;
@@ -251,60 +253,27 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
if (pdacpu(cpu)->sn_first_irq == irq) {
foundmatch = 0;
- for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++) {
- tmp_irq_info = sn_irq[i];
- while (tmp_irq_info) {
+ for (i = pdacpu(cpu)->sn_first_irq + 1;
+ i < NR_IRQS && !foundmatch; i++) {
+ list_for_each_entry_rcu(tmp_irq_info,
+ sn_irq_lh[i],
+ list) {
if (tmp_irq_info->irq_cpuid == cpu) {
- foundmatch++;
+ foundmatch = 1;
break;
}
- tmp_irq_info = tmp_irq_info->irq_next;
- }
- if (foundmatch) {
- break;
}
}
pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i);
}
+ rcu_read_unlock();
}
-struct sn_irq_info *sn_irq_alloc(nasid_t local_nasid, int local_widget, int irq,
- nasid_t nasid, int slice)
+static void sn_irq_info_free(struct rcu_head *head)
{
struct sn_irq_info *sn_irq_info;
- int status;
-
- sn_irq_info = kmalloc(sizeof(*sn_irq_info), GFP_KERNEL);
- if (sn_irq_info == NULL)
- return NULL;
-
- memset(sn_irq_info, 0x0, sizeof(*sn_irq_info));
-
- status =
- sn_intr_alloc(local_nasid, local_widget, __pa(sn_irq_info), irq,
- nasid, slice);
-
- if (status) {
- kfree(sn_irq_info);
- return NULL;
- } else {
- return sn_irq_info;
- }
-}
-
-void sn_irq_free(struct sn_irq_info *sn_irq_info)
-{
- uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge;
- nasid_t local_nasid = NASID_GET(bridge);
- int local_widget;
-
- if (local_nasid & 1) /* tio check */
- local_widget = TIO_SWIN_WIDGETNUM(bridge);
- else
- local_widget = SWIN_WIDGETNUM(bridge);
-
- sn_intr_free(local_nasid, local_widget, sn_irq_info);
+ sn_irq_info = container_of(head, struct sn_irq_info, rcu);
kfree(sn_irq_info);
}
@@ -314,30 +283,54 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
int slice = sn_irq_info->irq_slice;
int cpu = nasid_slice_to_cpuid(nasid, slice);
+ pci_dev_get(pci_dev);
sn_irq_info->irq_cpuid = cpu;
sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev);
/* link it into the sn_irq[irq] list */
- sn_irq_info->irq_next = sn_irq[sn_irq_info->irq_irq];
- sn_irq[sn_irq_info->irq_irq] = sn_irq_info;
+ spin_lock(&sn_irq_info_lock);
+ list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
+ spin_unlock(&sn_irq_info_lock);
(void)register_intr_pda(sn_irq_info);
}
+void sn_irq_unfixup(struct pci_dev *pci_dev)
+{
+ struct sn_irq_info *sn_irq_info;
+
+ /* Only cleanup IRQ stuff if this device has a host bus context */
+ if (!SN_PCIDEV_BUSSOFT(pci_dev))
+ return;
+
+ sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info;
+ if (!sn_irq_info || !sn_irq_info->irq_irq) {
+ kfree(sn_irq_info);
+ return;
+ }
+
+ unregister_intr_pda(sn_irq_info);
+ spin_lock(&sn_irq_info_lock);
+ list_del_rcu(&sn_irq_info->list);
+ spin_unlock(&sn_irq_info_lock);
+ call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
+ pci_dev_put(pci_dev);
+}
+
static void force_interrupt(int irq)
{
struct sn_irq_info *sn_irq_info;
if (!sn_ioif_inited)
return;
- sn_irq_info = sn_irq[irq];
- while (sn_irq_info) {
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) {
if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
- (sn_irq_info->irq_bridge != NULL)) {
+ (sn_irq_info->irq_bridge != NULL))
pcibr_force_interrupt(sn_irq_info);
- }
- sn_irq_info = sn_irq_info->irq_next;
}
+ rcu_read_unlock();
}
/*
@@ -402,19 +395,41 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
void sn_lb_int_war_check(void)
{
+ struct sn_irq_info *sn_irq_info;
int i;
if (!sn_ioif_inited || pda->sn_first_irq == 0)
return;
+
+ rcu_read_lock();
for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
- struct sn_irq_info *sn_irq_info = sn_irq[i];
- while (sn_irq_info) {
- /* Only call for PCI bridges that are fully initialized. */
+ list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
+ /*
+ * Only call for PCI bridges that are fully
+ * initialized.
+ */
if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
- (sn_irq_info->irq_bridge != NULL)) {
+ (sn_irq_info->irq_bridge != NULL))
sn_check_intr(i, sn_irq_info);
- }
- sn_irq_info = sn_irq_info->irq_next;
}
}
+ rcu_read_unlock();
+}
+
+void sn_irq_lh_init(void)
+{
+ int i;
+
+ sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL);
+ if (!sn_irq_lh)
+ panic("SN PCI INIT: Failed to allocate memory for PCI init\n");
+
+ for (i = 0; i < NR_IRQS; i++) {
+ sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL);
+ if (!sn_irq_lh[i])
+ panic("SN PCI INIT: Failed IRQ memory allocation\n");
+
+ INIT_LIST_HEAD(sn_irq_lh[i]);
+ }
+
}
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 44bfc7f318c..7c7fe441d62 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -36,6 +36,7 @@
#include <asm/machvec.h>
#include <asm/system.h>
#include <asm/processor.h>
+#include <asm/vga.h>
#include <asm/sn/arch.h>
#include <asm/sn/addrs.h>
#include <asm/sn/pda.h>
@@ -95,6 +96,7 @@ u8 sn_coherency_id;
EXPORT_SYMBOL(sn_coherency_id);
u8 sn_region_size;
EXPORT_SYMBOL(sn_region_size);
+int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
short physical_node_map[MAX_PHYSNODE_ID];
@@ -268,19 +270,22 @@ void __init sn_setup(char **cmdline_p)
{
long status, ticks_per_sec, drift;
int pxm;
- int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+ u32 version = sn_sal_rev();
extern void sn_cpu_init(void);
ia64_sn_plat_set_error_handling_features();
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
/*
- * If the generic code has enabled vga console support - lets
- * get rid of it again. This is a kludge for the fact that ACPI
- * currtently has no way of informing us if legacy VGA is available
- * or not.
+ * If there was a primary vga adapter identified through the
+ * EFI PCDP table, make it the preferred console. Otherwise
+ * zero out conswitchp.
*/
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
- if (conswitchp == &vga_con) {
+
+ if (vga_console_membase) {
+ /* usable vga ... make tty0 the preferred default console */
+ add_preferred_console("tty", 0, NULL);
+ } else {
printk(KERN_DEBUG "SGI: Disabling VGA console\n");
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
@@ -303,22 +308,21 @@ void __init sn_setup(char **cmdline_p)
* support here so we don't have to listen to failed keyboard probe
* messages.
*/
- if ((major < 2 || (major == 2 && minor <= 9)) &&
- acpi_kbd_controller_present) {
+ if (version <= 0x0209 && acpi_kbd_controller_present) {
printk(KERN_INFO "Disabling legacy keyboard support as prom "
"is too old and doesn't provide FADT\n");
acpi_kbd_controller_present = 0;
}
- printk("SGI SAL version %x.%02x\n", major, minor);
+ printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
/*
* Confirm the SAL we're running on is recent enough...
*/
- if ((major < SN_SAL_MIN_MAJOR) || (major == SN_SAL_MIN_MAJOR &&
- minor < SN_SAL_MIN_MINOR)) {
+ if (version < SN_SAL_MIN_VERSION) {
printk(KERN_ERR "This kernel needs SGI SAL version >= "
- "%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR);
+ "%x.%02x\n", SN_SAL_MIN_VERSION >> 8,
+ SN_SAL_MIN_VERSION & 0x00FF);
panic("PROM version too old\n");
}
@@ -350,7 +354,7 @@ void __init sn_setup(char **cmdline_p)
ia64_mark_idle = &snidle;
- /*
+ /*
* For the bootcpu, we do this here. All other cpus will make the
* call as part of cpu_init in slave cpu initialization.
*/
@@ -397,7 +401,7 @@ static void __init sn_init_pdas(char **cmdline_p)
nodepdaindr[cnode] =
alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
- memset(nodepdaindr[cnode]->phys_cpuid, -1,
+ memset(nodepdaindr[cnode]->phys_cpuid, -1,
sizeof(nodepdaindr[cnode]->phys_cpuid));
}
@@ -427,7 +431,7 @@ static void __init sn_init_pdas(char **cmdline_p)
}
/*
- * Initialize the per node hubdev. This includes IO Nodes and
+ * Initialize the per node hubdev. This includes IO Nodes and
* headless/memless nodes.
*/
for (cnode = 0; cnode < numionodes; cnode++) {
@@ -455,6 +459,14 @@ void __init sn_cpu_init(void)
int i;
static int wars_have_been_checked;
+ if (smp_processor_id() == 0 && IS_MEDUSA()) {
+ if (ia64_sn_is_fake_prom())
+ sn_prom_type = 2;
+ else
+ sn_prom_type = 1;
+ printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+ }
+
memset(pda, 0, sizeof(pda));
if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
&sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
@@ -520,7 +532,7 @@ void __init sn_cpu_init(void)
*/
{
u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
- u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
+ u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
u64 *pio;
pio = is_shub1() ? pio1 : pio2;
@@ -552,6 +564,10 @@ static void __init scan_for_ionodes(void)
int nasid = 0;
lboard_t *brd;
+ /* fakeprom does not support klgraph */
+ if (IS_RUNNING_ON_FAKE_PROM())
+ return;
+
/* Setup ionodes with memory */
for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
char *klgraph_header;
@@ -563,8 +579,6 @@ static void __init scan_for_ionodes(void)
cnodeid = -1;
klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
if (!klgraph_header) {
- if (IS_RUNNING_ON_SIMULATOR())
- continue;
BUG(); /* All nodes must have klconfig tables! */
}
cnodeid = nasid_to_cnodeid(nasid);
@@ -630,8 +644,8 @@ int
nasid_slice_to_cpuid(int nasid, int slice)
{
long cpu;
-
- for (cpu=0; cpu < NR_CPUS; cpu++)
+
+ for (cpu=0; cpu < NR_CPUS; cpu++)
if (cpuid_to_nasid(cpu) == nasid &&
cpuid_to_slice(cpu) == slice)
return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
index 7947312801e..96cb71d1568 100644
--- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -6,6 +6,7 @@
* Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
*/
+#include <asm/types.h>
#include <asm/sn/shub_mmr.h>
#define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index a087b274847..254fe15c064 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -8,12 +8,12 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/delay.h>
+#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/sn/sn_sal.h>
#include <asm/sn/addrs.h>
@@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num,
cx_dev->dev.parent = NULL;
cx_dev->dev.bus = &tiocx_bus_type;
cx_dev->dev.release = tiocx_bus_release;
- snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x",
- cx_dev->cx_id.nasid, cx_dev->cx_id.part_num);
+ snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d",
+ cx_dev->cx_id.nasid);
device_register(&cx_dev->dev);
get_device(&cx_dev->dev);
@@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *cx_dev)
*/
static int cx_device_reload(struct cx_dev *cx_dev)
{
- device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control);
cx_device_unregister(cx_dev);
return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
cx_dev->cx_id.mfg_num, cx_dev->hubdev);
@@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid)
switch (tiocx_btchar_get(nasid)) {
case L1_BRICKTYPE_SA:
case L1_BRICKTYPE_ATHENA:
+ case L1_BRICKTYPE_DAYTONA:
return 1;
}
return 0;
@@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
uint64_t cx_id;
cx_id =
- *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+ *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
WIDGET_ID);
part_num = XWIDGET_PART_NUM(cx_id);
mfg_num = XWIDGET_MFG_NUM(cx_id);
@@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *
switch (n) {
case 1:
+ tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
+ tiocx_reload(cx_dev);
+ break;
+ case 2:
tiocx_reload(cx_dev);
break;
case 3:
@@ -477,6 +481,9 @@ static int __init tiocx_init(void)
cnodeid_t cnodeid;
int found_tiocx_device = 0;
+ if (!ia64_platform_is("sn2"))
+ return -ENODEV;
+
bus_register(&tiocx_bus_type);
for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) {
@@ -537,7 +544,7 @@ static void __exit tiocx_exit(void)
bus_unregister(&tiocx_bus_type);
}
-module_init(tiocx_init);
+subsys_initcall(tiocx_init);
module_exit(tiocx_exit);
/************************************************************************
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
index 1a0aed8490d..d0ee635daf2 100644
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -87,7 +87,7 @@ struct xpc_rsvd_page {
u8 partid; /* partition ID from SAL */
u8 version;
u8 pad[6]; /* pad to u64 align */
- u64 vars_pa;
+ volatile u64 vars_pa;
u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
};
@@ -138,7 +138,7 @@ struct xpc_vars {
* occupies half a cacheline.
*/
struct xpc_vars_part {
- u64 magic;
+ volatile u64 magic;
u64 openclose_args_pa; /* physical address of open and close args */
u64 GPs_pa; /* physical address of Get/Put values */
@@ -185,8 +185,8 @@ struct xpc_vars_part {
* Define a Get/Put value pair (pointers) used with a message queue.
*/
struct xpc_gp {
- s64 get; /* Get value */
- s64 put; /* Put value */
+ volatile s64 get; /* Get value */
+ volatile s64 put; /* Put value */
};
#define XPC_GP_SIZE \
@@ -231,7 +231,7 @@ struct xpc_openclose_args {
*/
struct xpc_notify {
struct semaphore sema; /* notify semaphore */
- u8 type; /* type of notification */
+ volatile u8 type; /* type of notification */
/* the following two fields are only used if type == XPC_N_CALL */
xpc_notify_func func; /* user's notify function */
@@ -439,7 +439,7 @@ struct xpc_partition {
/* XPC infrastructure referencing and teardown control */
- u8 setup_state; /* infrastructure setup state */
+ volatile u8 setup_state; /* infrastructure setup state */
wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */
atomic_t references; /* #of references to infrastructure */
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 0bf6fbcc46d..94698bea7be 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -72,7 +72,7 @@ xpc_initialize_channels(struct xpc_partition *part, partid_t partid)
enum xpc_retval
xpc_setup_infrastructure(struct xpc_partition *part)
{
- int ret;
+ int ret, cpuid;
struct timer_list *timer;
partid_t partid = XPC_PARTID(part);
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
* With the setting of the partition setup_state to XPC_P_SETUP, we're
* declaring that this partition is ready to go.
*/
- (volatile u8) part->setup_state = XPC_P_SETUP;
+ part->setup_state = XPC_P_SETUP;
/*
@@ -223,11 +223,11 @@ xpc_setup_infrastructure(struct xpc_partition *part)
xpc_vars_part[partid].openclose_args_pa =
__pa(part->local_openclose_args);
xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
- xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id());
- xpc_vars_part[partid].IPI_phys_cpuid =
- cpu_physical_id(smp_processor_id());
+ cpuid = raw_smp_processor_id(); /* any CPU in this partition will do */
+ xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(cpuid);
+ xpc_vars_part[partid].IPI_phys_cpuid = cpu_physical_id(cpuid);
xpc_vars_part[partid].nchannels = part->nchannels;
- (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+ xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
return xpcSuccess;
}
@@ -355,7 +355,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
/* let the other side know that we've pulled their variables */
- (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
+ xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
}
if (pulled_entry->magic == XPC_VP_MAGIC1) {
@@ -1183,7 +1183,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
*/
xpc_clear_local_msgqueue_flags(ch);
- (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get;
+ ch->w_remote_GP.get = ch->remote_GP.get;
dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
"channel=%d\n", ch->w_remote_GP.get, ch->partid,
@@ -1211,7 +1211,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
*/
xpc_clear_remote_msgqueue_flags(ch);
- (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put;
+ ch->w_remote_GP.put = ch->remote_GP.put;
dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
"channel=%d\n", ch->w_remote_GP.put, ch->partid,
@@ -1875,7 +1875,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
notify = &ch->notify_queue[msg_number % ch->local_nentries];
notify->func = func;
notify->key = key;
- (volatile u8) notify->type = notify_type;
+ notify->type = notify_type;
// >>> is a mb() needed here?
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
index 177ddb748eb..bb1d5cf3044 100644
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -53,6 +53,7 @@
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
+#include <linux/delay.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include <asm/uaccess.h>
@@ -308,8 +309,7 @@ xpc_make_first_contact(struct xpc_partition *part)
"partition %d\n", XPC_PARTID(part));
/* wait a 1/4 of a second or so */
- set_current_state(TASK_INTERRUPTIBLE);
- (void) schedule_timeout(0.25 * HZ);
+ msleep_interruptible(250);
if (part->act_state == XPC_P_DEACTIVATING) {
return part->reason;
@@ -420,7 +420,7 @@ xpc_activating(void *__partid)
partid_t partid = (u64) __partid;
struct xpc_partition *part = &xpc_partitions[partid];
unsigned long irq_flags;
- struct sched_param param = { sched_priority: MAX_USER_RT_PRIO - 1 };
+ struct sched_param param = { sched_priority: MAX_RT_PRIO - 1 };
int ret;
@@ -841,9 +841,7 @@ xpc_do_exit(void)
down(&xpc_discovery_exited);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(0.3 * HZ);
- set_current_state(TASK_RUNNING);
+ msleep_interruptible(300);
/* wait for all partitions to become inactive */
@@ -860,12 +858,8 @@ xpc_do_exit(void)
}
}
- if (active_part_count) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(0.3 * HZ);
- set_current_state(TASK_RUNNING);
- }
-
+ if (active_part_count)
+ msleep_interruptible(300);
} while (active_part_count > 0);
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
index cd7ed73f0e7..578265ea9e6 100644
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -253,7 +253,7 @@ xpc_rsvd_page_init(void)
* This signifies to the remote partition that our reserved
* page is initialized.
*/
- (volatile u64) rp->vars_pa = __pa(xpc_vars);
+ rp->vars_pa = __pa(xpc_vars);
return rp;
}
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 5da9bdbde7c..0e4b9ad9ef0 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -11,9 +11,10 @@
#include <linux/module.h>
#include <asm/dma.h>
-#include <asm/sn/sn_sal.h>
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
+#include <asm/sn/sn_sal.h>
#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
@@ -78,6 +79,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
{
void *cpuaddr;
unsigned long phys_addr;
+ int node;
struct pci_dev *pdev = to_pci_dev(dev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -85,10 +87,19 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
/*
* Allocate the memory.
- * FIXME: We should be doing alloc_pages_node for the node closest
- * to the PCI device.
*/
- if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+ node = pcibus_to_node(pdev->bus);
+ if (likely(node >=0)) {
+ struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
+
+ if (likely(p))
+ cpuaddr = page_address(p);
+ else
+ return NULL;
+ } else
+ cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+
+ if (unlikely(!cpuaddr))
return NULL;
memset(cpuaddr, 0x0, size);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
index 0e47bce85f2..d1647b863e6 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -8,9 +8,9 @@
#include <linux/types.h>
#include <asm/sn/sn_sal.h>
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
int pcibr_invalidate_ate = 0; /* by default don't invalidate ATE on free */
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 64af2b2c178..b058dc2a0b9 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -8,18 +8,17 @@
#include <linux/types.h>
#include <linux/pci.h>
-#include <asm/sn/sn_sal.h>
+#include <asm/sn/addrs.h>
#include <asm/sn/geo.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-#include "pci/tiocp.h"
-#include "pci/pic.h"
-#include "pci/pcibr_provider.h"
-#include "pci/tiocp.h"
+#include <asm/sn/pic.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/tiocp.h>
#include "tio.h"
-#include <asm/sn/addrs.h>
+#include "xtalk/xwidgetdev.h"
+#include "xtalk/hubdev.h"
extern int sn_ioif_inited;
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 3893999d23d..b95e928636a 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -6,18 +6,51 @@
* Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
*/
-#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/types.h>
#include <linux/pci.h>
-#include <asm/sn/sn_sal.h>
-#include "xtalk/xwidgetdev.h"
+#include <asm/sn/addrs.h>
#include <asm/sn/geo.h>
-#include "xtalk/hubdev.h"
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
-#include <asm/sn/addrs.h>
+#include <asm/sn/sn_sal.h>
+#include "xtalk/xwidgetdev.h"
+#include "xtalk/hubdev.h"
+
+int
+sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp)
+{
+ struct ia64_sal_retval ret_stuff;
+ uint64_t busnum;
+
+ ret_stuff.status = 0;
+ ret_stuff.v0 = 0;
+ busnum = soft->pbi_buscommon.bs_persist_busnum;
+ SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum,
+ (u64) device, (u64) resp, 0, 0, 0, 0);
+
+ return (int)ret_stuff.v0;
+}
+
+int
+sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
+ void *resp)
+{
+ struct ia64_sal_retval ret_stuff;
+ uint64_t busnum;
+
+ ret_stuff.status = 0;
+ ret_stuff.v0 = 0;
+
+ busnum = soft->pbi_buscommon.bs_persist_busnum;
+ SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
+ (u64) busnum, (u64) device, (u64) action,
+ (u64) resp, 0, 0, 0);
+
+ return (int)ret_stuff.v0;
+}
static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
{
@@ -52,7 +85,7 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs)
}
void *
-pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
{
int nasid, cnode, j;
struct hubdev_info *hubdev_info;
@@ -125,6 +158,14 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft)
memset(soft->pbi_int_ate_resource.ate, 0,
(soft->pbi_int_ate_size * sizeof(uint64_t)));
+ if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP)
+ /*
+ * TIO PCI Bridge with no closest node information.
+ * FIXME: Find another way to determine the closest node
+ */
+ controller->node = -1;
+ else
+ controller->node = cnode;
return soft;
}
@@ -188,3 +229,6 @@ pcibr_init_provider(void)
return 0;
}
+
+EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable);
+EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 865c11c3b50..21426d02fbe 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -6,13 +6,13 @@
* Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
*/
-#include <linux/types.h>
#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
-#include "pci/tiocp.h"
-#include "pci/pic.h"
-#include "pci/pcibr_provider.h"
+#include <asm/sn/pic.h>
+#include <asm/sn/tiocp.h>
union br_ptr {
struct tiocp tio;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 8dae9eb4545..5d76a758146 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
if (!ct_addr)
return 0;
- bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff);
+ bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
node_upper = ct_addr >> 48;
if (node_upper > 64) {
@@ -464,7 +464,7 @@ map_return:
* For mappings created using the direct modes (64 or 48) there are no
* resources to release.
*/
-void
+static void
tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
{
int i, entry;
@@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
* The mapping mode used is based on the devices dma_mask. As a last resort
* use the GART mapped mode.
*/
-uint64_t
+static uint64_t
tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
{
uint64_t mapaddr;
@@ -580,8 +580,8 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
* On successful setup, returns the kernel version of tioca_common back to
* the caller.
*/
-void *
-tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+static void *
+tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
{
struct tioca_common *tioca_common;
struct tioca_kernel *tioca_kern;
@@ -589,8 +589,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
/* sanity check prom rev */
- if (sn_sal_rev_major() < 4 ||
- (sn_sal_rev_major() == 4 && sn_sal_rev_minor() < 6)) {
+ if (sn_sal_rev() < 0x0406) {
printk
(KERN_ERR "%s: SGI prom rev 4.06 or greater required "
"for tioca support\n", __FUNCTION__);
@@ -647,6 +646,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
__FUNCTION__, SGI_TIOCA_ERROR,
(int)tioca_common->ca_common.bs_persist_busnum);
+ /* Setup locality information */
+ controller->node = tioca_kern->ca_closest_node;
return tioca_common;
}