Merge by hand from Linus' tree.

Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Paul Mackerras 2005-09-29 13:13:36 +10:00
commit ab11d1ea28
180 changed files with 3631 additions and 3091 deletions

View file

@ -237,6 +237,12 @@ udev
udev is a userspace application for populating /dev dynamically with
only entries for devices actually present. udev replaces devfs.
FUSE
----
Needs libfuse 2.4.0 or later. Absolute minimum is 2.3.0 but mount
options 'direct_io' and 'kernel_cache' won't work.
Networking
==========
@ -390,6 +396,10 @@ udev
----
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
FUSE
----
o <http://sourceforge.net/projects/fuse>
Networking
**********

View file

@ -195,8 +195,8 @@ KEY ACCESS PERMISSIONS
======================
Keys have an owner user ID, a group access ID, and a permissions mask. The mask
has up to eight bits each for user, group and other access. Only five of each
set of eight bits are defined. These permissions granted are:
has up to eight bits each for possessor, user, group and other access. Only
five of each set of eight bits are defined. These permissions granted are:
(*) View
@ -241,16 +241,16 @@ about the status of the key service:
type, description and permissions. The payload of the key is not available
this way:
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
00000001 I----- 39 perm 1f0000 0 0 keyring _uid_ses.0: 1/4
00000002 I----- 2 perm 1f0000 0 0 keyring _uid.0: empty
00000007 I----- 1 perm 1f0000 0 0 keyring _pid.1: empty
0000018d I----- 1 perm 1f0000 0 0 keyring _pid.412: empty
000004d2 I--Q-- 1 perm 1f0000 32 -1 keyring _uid.32: 1/4
000004d3 I--Q-- 3 perm 1f0000 32 -1 keyring _uid_ses.32: empty
00000892 I--QU- 1 perm 1f0000 0 0 user metal:copper: 0
00000893 I--Q-N 1 35s 1f0000 0 0 user metal:silver: 0
00000894 I--Q-- 1 10h 1f0000 0 0 user metal:gold: 0
SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
The flags are:
@ -637,6 +637,34 @@ call, and the key released upon close. How to deal with conflicting keys due to
two different users opening the same file is left to the filesystem author to
solve.
Note that there are two different types of pointers to keys that may be
encountered:
(*) struct key *
This simply points to the key structure itself. Key structures will be at
least four-byte aligned.
(*) key_ref_t
This is equivalent to a struct key *, but the least significant bit is set
if the caller "possesses" the key. By "possession" it is meant that the
calling processes has a searchable link to the key from one of its
keyrings. There are three functions for dealing with these:
key_ref_t make_key_ref(const struct key *key,
unsigned long possession);
struct key *key_ref_to_ptr(const key_ref_t key_ref);
unsigned long is_key_possessed(const key_ref_t key_ref);
The first function constructs a key reference from a key pointer and
possession information (which must be 0 or 1 and not any other value).
The second function retrieves the key pointer from a reference and the
third retrieves the possession flag.
When accessing a key's payload contents, certain precautions must be taken to
prevent access vs modification races. See the section "Notes on accessing
payload contents" for more information.
@ -665,7 +693,11 @@ payload contents" for more information.
void key_put(struct key *key);
This can be called from interrupt context. If CONFIG_KEYS is not set then
Or:
void key_ref_put(key_ref_t key_ref);
These can be called from interrupt context. If CONFIG_KEYS is not set then
the argument will not be parsed.
@ -689,13 +721,17 @@ payload contents" for more information.
(*) If a keyring was found in the search, this can be further searched by:
struct key *keyring_search(struct key *keyring,
const struct key_type *type,
const char *description)
key_ref_t keyring_search(key_ref_t keyring_ref,
const struct key_type *type,
const char *description)
This searches the keyring tree specified for a matching key. Error ENOKEY
is returned upon failure. If successful, the returned key will need to be
released.
is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
the returned key will need to be released.
The possession attribute from the keyring reference is used to control
access through the permissions mask and is propagated to the returned key
reference pointer if successful.
(*) To check the validity of a key, this function can be called:
@ -732,7 +768,7 @@ More complex payload contents must be allocated and a pointer to them set in
key->payload.data. One of the following ways must be selected to access the
data:
(1) Unmodifyable key type.
(1) Unmodifiable key type.
If the key type does not have a modify method, then the key's payload can
be accessed without any form of locking, provided that it's known to be

View file

@ -604,6 +604,15 @@ P: H. Peter Anvin
M: hpa@zytor.com
S: Maintained
CPUSETS
P: Paul Jackson
P: Simon Derr
M: pj@sgi.com
M: simon.derr@bull.net
L: linux-kernel@vger.kernel.org
W: http://www.bullopensource.org/cpuset/
S: Supported
CRAMFS FILESYSTEM
W: http://sourceforge.net/projects/cramfs/
S: Orphan
@ -1906,6 +1915,13 @@ M: joern@wh.fh-wedel.de
L: linux-mtd@lists.infradead.org
S: Maintained
PKTCDVD DRIVER
P: Peter Osterlund
M: petero2@telia.com
L: linux-kernel@vger.kernel.org
L: packet-writing@suse.com
S: Maintained
POSIX CLOCKS and TIMERS
P: George Anzinger
M: george@mvista.com

View file

@ -175,10 +175,10 @@ else
endif
@touch $@
archprepare: maketools include/asm-arm/.arch
archprepare: maketools
.PHONY: maketools FORCE
maketools: include/linux/version.h FORCE
maketools: include/linux/version.h include/asm-arm/.arch FORCE
$(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
# Convert bzImage to zImage

View file

@ -1,14 +1,13 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-rc1-bk2
# Sun Mar 27 22:53:40 2005
# Linux kernel version: 2.6.14-rc1-git5
# Tue Sep 20 17:26:28 2005
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_IOMAP=y
#
# Code maturity level options
@ -16,11 +15,13 @@ CONFIG_GENERIC_IOMAP=y
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
# CONFIG_POSIX_MQUEUE is not set
@ -31,10 +32,13 @@ CONFIG_SYSCTL=y
# CONFIG_HOTPLUG is not set
CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_EMBEDDED=y
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
@ -81,6 +85,7 @@ CONFIG_ARCH_IXP4XX=y
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
#
@ -90,15 +95,16 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
#
# IXP4xx Platforms
#
# CONFIG_ARCH_AVILA is not set
CONFIG_ARCH_AVILA=y
CONFIG_ARCH_ADI_COYOTE=y
CONFIG_ARCH_IXDP425=y
# CONFIG_MACH_IXDPG425 is not set
# CONFIG_MACH_IXDP465 is not set
CONFIG_MACH_IXDPG425=y
CONFIG_MACH_IXDP465=y
CONFIG_ARCH_IXCDP1100=y
CONFIG_ARCH_PRPMC1100=y
CONFIG_ARCH_IXDP4XX=y
# CONFIG_MACH_GTWX5715 is not set
CONFIG_CPU_IXP46X=y
CONFIG_MACH_GTWX5715=y
#
# IXP4xx Options
@ -114,7 +120,6 @@ CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_MINICACHE=y
#
# Processor Features
@ -127,9 +132,10 @@ CONFIG_DMABOUNCE=y
#
# Bus support
#
CONFIG_ISA_DMA_API=y
CONFIG_PCI=y
CONFIG_PCI_LEGACY_PROC=y
CONFIG_PCI_NAMES=y
# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
@ -140,6 +146,15 @@ CONFIG_PCI_NAMES=y
# Kernel Features
#
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_SPARSEMEM_STATIC is not set
CONFIG_ALIGNMENT_TRAP=y
#
@ -174,6 +189,241 @@ CONFIG_BINFMT_ELF=y
CONFIG_PM=y
CONFIG_APM=y
#
# Networking
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=m
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=m
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_BIC=y
#
# IP: Virtual Server Configuration
#
CONFIG_IP_VS=m
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
# CONFIG_IP_VS_PROTO_TCP is not set
# CONFIG_IP_VS_PROTO_UDP is not set
# CONFIG_IP_VS_PROTO_ESP is not set
# CONFIG_IP_VS_PROTO_AH is not set
#
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
# CONFIG_IP_VS_SED is not set
# CONFIG_IP_VS_NQ is not set
#
# IPVS application helper
#
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
# CONFIG_NETFILTER_NETLINK is not set
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
# CONFIG_IP_NF_CONNTRACK_MARK is not set
# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
# CONFIG_IP_NF_NETBIOS_NS is not set
# CONFIG_IP_NF_TFTP is not set
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
# CONFIG_IP_NF_MATCH_IPRANGE is not set
CONFIG_IP_NF_MATCH_MAC=m
# CONFIG_IP_NF_MATCH_PKTTYPE is not set
CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
# CONFIG_IP_NF_MATCH_RECENT is not set
# CONFIG_IP_NF_MATCH_ECN is not set
# CONFIG_IP_NF_MATCH_DSCP is not set
CONFIG_IP_NF_MATCH_AH_ESP=m
CONFIG_IP_NF_MATCH_LENGTH=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_MATCH_TCPMSS=m
# CONFIG_IP_NF_MATCH_HELPER is not set
CONFIG_IP_NF_MATCH_STATE=m
# CONFIG_IP_NF_MATCH_CONNTRACK is not set
CONFIG_IP_NF_MATCH_OWNER=m
# CONFIG_IP_NF_MATCH_PHYSDEV is not set
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
# CONFIG_IP_NF_MATCH_REALM is not set
# CONFIG_IP_NF_MATCH_SCTP is not set
# CONFIG_IP_NF_MATCH_DCCP is not set
# CONFIG_IP_NF_MATCH_COMMENT is not set
# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
# CONFIG_IP_NF_MATCH_STRING is not set
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
# CONFIG_IP_NF_TARGET_NETMAP is not set
# CONFIG_IP_NF_TARGET_SAME is not set
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
# CONFIG_IP_NF_TARGET_ECN is not set
# CONFIG_IP_NF_TARGET_DSCP is not set
CONFIG_IP_NF_TARGET_MARK=m
# CONFIG_IP_NF_TARGET_CLASSIFY is not set
# CONFIG_IP_NF_TARGET_TTL is not set
# CONFIG_IP_NF_RAW is not set
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
# CONFIG_IP_NF_ARP_MANGLE is not set
#
# Bridge: Netfilter Configuration
#
# CONFIG_BRIDGE_NF_EBTABLES is not set
#
# DCCP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_DCCP is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
CONFIG_ATM=y
CONFIG_ATM_CLIP=y
# CONFIG_ATM_CLIP_NO_ICMP is not set
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
# CONFIG_DECNET is not set
CONFIG_LLC=m
# CONFIG_LLC2 is not set
CONFIG_IPX=m
# CONFIG_IPX_INTERN is not set
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
CONFIG_X25=m
CONFIG_LAPB=m
# CONFIG_NET_DIVERT is not set
CONFIG_ECONET=m
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
# CONFIG_NET_SCH_CLK_CPU is not set
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
# CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_ATM is not set
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
# CONFIG_NET_SCH_NETEM is not set
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_BASIC is not set
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_PERF is not set
# CONFIG_NET_CLS_IND is not set
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_IEEE80211 is not set
#
# Device Drivers
#
@ -244,6 +494,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_IXP4XX=y
# CONFIG_MTD_EDB7312 is not set
# CONFIG_MTD_PCI is not set
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
@ -283,7 +534,6 @@ CONFIG_MTD_NAND_IDS=m
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@ -297,7 +547,6 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CDROM_PKTCDVD is not set
#
@ -351,6 +600,7 @@ CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_HPT366=y
# 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=y
@ -369,6 +619,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
#
@ -379,6 +630,7 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# Fusion MPT device support
#
# CONFIG_FUSION is not set
#
# IEEE 1394 (FireWire) support
@ -391,241 +643,24 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_I2O is not set
#
# Networking support
# Network device support
#
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=m
CONFIG_PACKET_MMAP=y
CONFIG_NETLINK_DEV=m
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_FWMARK=y
CONFIG_IP_ROUTE_MULTIPATH=y
# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
CONFIG_NET_IPGRE=m
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
CONFIG_INET_TUNNEL=m
# CONFIG_IP_TCPDIAG is not set
# CONFIG_IP_TCPDIAG_IPV6 is not set
#
# IP: Virtual Server Configuration
#
CONFIG_IP_VS=m
CONFIG_IP_VS_DEBUG=y
CONFIG_IP_VS_TAB_BITS=12
#
# IPVS transport protocol load balancing support
#
# CONFIG_IP_VS_PROTO_TCP is not set
# CONFIG_IP_VS_PROTO_UDP is not set
# CONFIG_IP_VS_PROTO_ESP is not set
# CONFIG_IP_VS_PROTO_AH is not set
#
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
# CONFIG_IP_VS_SED is not set
# CONFIG_IP_VS_NQ is not set
#
# IPVS application helper
#
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
CONFIG_BRIDGE_NETFILTER=y
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_CONNTRACK=m
# CONFIG_IP_NF_CT_ACCT is not set
# CONFIG_IP_NF_CONNTRACK_MARK is not set
# CONFIG_IP_NF_CT_PROTO_SCTP is not set
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
# CONFIG_IP_NF_TFTP is not set
# CONFIG_IP_NF_AMANDA is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
# CONFIG_IP_NF_MATCH_IPRANGE is not set
CONFIG_IP_NF_MATCH_MAC=m
# CONFIG_IP_NF_MATCH_PKTTYPE is not set
CONFIG_IP_NF_MATCH_MARK=m
CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
# CONFIG_IP_NF_MATCH_RECENT is not set
# CONFIG_IP_NF_MATCH_ECN is not set
# CONFIG_IP_NF_MATCH_DSCP is not set
CONFIG_IP_NF_MATCH_AH_ESP=m
CONFIG_IP_NF_MATCH_LENGTH=m
CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_MATCH_TCPMSS=m
# CONFIG_IP_NF_MATCH_HELPER is not set
CONFIG_IP_NF_MATCH_STATE=m
# CONFIG_IP_NF_MATCH_CONNTRACK is not set
CONFIG_IP_NF_MATCH_OWNER=m
# CONFIG_IP_NF_MATCH_PHYSDEV is not set
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
# CONFIG_IP_NF_MATCH_REALM is not set
# CONFIG_IP_NF_MATCH_SCTP is not set
# CONFIG_IP_NF_MATCH_COMMENT is not set
# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_NAT=m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=m
CONFIG_IP_NF_TARGET_REDIRECT=m
# CONFIG_IP_NF_TARGET_NETMAP is not set
# CONFIG_IP_NF_TARGET_SAME is not set
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
# CONFIG_IP_NF_TARGET_ECN is not set
# CONFIG_IP_NF_TARGET_DSCP is not set
CONFIG_IP_NF_TARGET_MARK=m
# CONFIG_IP_NF_TARGET_CLASSIFY is not set
# CONFIG_IP_NF_RAW is not set
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
# CONFIG_IP_NF_ARP_MANGLE is not set
#
# Bridge: Netfilter Configuration
#
# CONFIG_BRIDGE_NF_EBTABLES is not set
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
#
# SCTP Configuration (EXPERIMENTAL)
#
# CONFIG_IP_SCTP is not set
CONFIG_ATM=y
CONFIG_ATM_CLIP=y
# CONFIG_ATM_CLIP_NO_ICMP is not set
CONFIG_ATM_LANE=m
CONFIG_ATM_MPOA=m
CONFIG_ATM_BR2684=m
# CONFIG_ATM_BR2684_IPFILTER is not set
CONFIG_BRIDGE=m
CONFIG_VLAN_8021Q=m
# CONFIG_DECNET is not set
CONFIG_LLC=m
# CONFIG_LLC2 is not set
CONFIG_IPX=m
# CONFIG_IPX_INTERN is not set
CONFIG_ATALK=m
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=m
CONFIG_IPDDP_ENCAP=y
CONFIG_IPDDP_DECAP=y
CONFIG_X25=m
CONFIG_LAPB=m
# CONFIG_NET_DIVERT is not set
CONFIG_ECONET=m
CONFIG_ECONET_AUNUDP=y
CONFIG_ECONET_NATIVE=y
CONFIG_WAN_ROUTER=m
#
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CLK_JIFFIES=y
# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
# CONFIG_NET_SCH_CLK_CPU is not set
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
# CONFIG_NET_SCH_HFSC is not set
# CONFIG_NET_SCH_ATM is not set
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
# CONFIG_NET_SCH_NETEM is not set
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_BASIC is not set
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
# CONFIG_CLS_U32_PERF is not set
# CONFIG_NET_CLS_IND is not set
# CONFIG_CLS_U32_MARK is not set
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
# CONFIG_NET_EMATCH is not set
# CONFIG_NET_CLS_ACT is not set
CONFIG_NET_CLS_POLICE=y
#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
CONFIG_NETDEVICES=y
CONFIG_DUMMY=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
#
# PHY device support
#
# CONFIG_PHYLIB is not set
#
# Ethernet (10 or 100Mbit)
#
@ -635,6 +670,7 @@ CONFIG_MII=y
# CONFIG_SUNGEM is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
#
# Tulip family network device support
@ -671,13 +707,17 @@ CONFIG_EEPRO100=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
#
# CONFIG_CHELSIO_T1 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
@ -702,6 +742,7 @@ CONFIG_NET_RADIO=y
CONFIG_HERMES=y
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
# CONFIG_NORTEL_HERMES is not set
CONFIG_PCI_HERMES=y
# CONFIG_ATMEL is not set
@ -709,6 +750,7 @@ CONFIG_PCI_HERMES=y
# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
#
# CONFIG_PRISM54 is not set
# CONFIG_HOSTAP is not set
CONFIG_NET_WIRELESS=y
#
@ -758,6 +800,8 @@ CONFIG_ATM_TCP=m
# CONFIG_SLIP is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
@ -795,7 +839,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
#
# Character devices
@ -816,6 +859,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
#
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
@ -882,12 +926,11 @@ CONFIG_I2C_ALGOBIT=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_IOP3XX is not set
# CONFIG_I2C_ISA is not set
CONFIG_I2C_IXP4XX=y
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
# CONFIG_SCx200_ACB is not set
@ -901,14 +944,33 @@ CONFIG_I2C_IXP4XX=y
# CONFIG_I2C_PCA_ISA is not set
#
# Hardware Sensors Chip support
# Miscellaneous I2C Chip support
#
CONFIG_I2C_SENSOR=y
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
CONFIG_SENSORS_EEPROM=y
# 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
# CONFIG_I2C_DEBUG_CHIP is not set
#
# Hardware Monitoring support
#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ADM1021 is not set
# 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
@ -924,32 +986,28 @@ CONFIG_I2C_SENSOR=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_SMSC47B397 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83627HF is not set
#
# Other I2C Chip support
#
CONFIG_SENSORS_EEPROM=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_RTC8564 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
#
# Misc devices
#
#
# Multimedia Capabilities Port drivers
#
#
# Multimedia devices
#
@ -994,6 +1052,7 @@ CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
# 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=y
@ -1004,17 +1063,15 @@ CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
#
# XFS support
#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@ -1034,12 +1091,10 @@ CONFIG_DNOTIFY=y
#
CONFIG_PROC_FS=y
CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@ -1054,8 +1109,7 @@ CONFIG_RAMFS=y
# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
# CONFIG_JFFS2_FS_NAND is not set
# CONFIG_JFFS2_FS_NOR_ECC is not set
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
@ -1072,12 +1126,14 @@ CONFIG_JFFS2_RTIME=y
#
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
@ -1086,6 +1142,7 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
# CONFIG_9P_FS is not set
#
# Partition Types
@ -1124,6 +1181,7 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_DEBUG_KERNEL=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
@ -1158,6 +1216,7 @@ CONFIG_DEBUG_LL=y
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y

View file

@ -125,7 +125,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
} else if (type & IRQT_LOW) {
int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
irq_type = IXP4XX_IRQ_LEVEL;
}
} else
return -EINVAL;
ixp4xx_config_irq(irq, irq_type);
@ -142,6 +143,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
/* Set the new style */
*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
return 0;
}
static void ixp4xx_irq_mask(unsigned int irq)

View file

@ -27,7 +27,6 @@
#include <linux/config.h>
#include <linux/acpi.h>
#include <linux/efi.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/dmi.h>

View file

@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>

View file

@ -7,7 +7,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

View file

@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

View file

@ -6,7 +6,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

View file

@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

View file

@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

View file

@ -6,7 +6,6 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/processor.h>

View file

@ -11,10 +11,8 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/reboot.h>
#include <linux/kexec.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/elf.h>
#include <linux/elfcore.h>

View file

@ -16,7 +16,6 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
@ -25,8 +24,6 @@
#include <asm/arch_hooks.h>
#include <asm/i8259.h>
#include <linux/irq.h>
#include <io_ports.h>
/*

View file

@ -21,7 +21,6 @@
*/
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>

View file

@ -14,7 +14,6 @@
*/
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/delay.h>

View file

@ -15,7 +15,6 @@
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>

View file

@ -47,13 +47,11 @@
#include <asm/ldt.h>
#include <asm/processor.h>
#include <asm/i387.h>
#include <asm/irq.h>
#include <asm/desc.h>
#ifdef CONFIG_MATH_EMULATION
#include <asm/math_emu.h>
#endif
#include <linux/irq.h>
#include <linux/err.h>
#include <asm/tlbflush.h>

View file

@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>

View file

@ -42,7 +42,6 @@
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/smp_lock.h>
#include <linux/irq.h>
#include <linux/bootmem.h>
#include <linux/notifier.h>
#include <linux/cpu.h>

View file

@ -6,7 +6,6 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/irq.h>
#include <linux/sysdev.h>
#include <linux/timex.h>
#include <asm/delay.h>

View file

@ -52,7 +52,6 @@
#include <asm/arch_hooks.h>
#include <asm/kdebug.h>
#include <linux/irq.h>
#include <linux/module.h>
#include "mach_traps.h"

View file

@ -5,7 +5,6 @@
#include <linux/config.h>
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
#include <asm/arch_hooks.h>

View file

@ -5,7 +5,6 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/fixmap.h>

View file

@ -19,7 +19,6 @@
#include <linux/config.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/smp_lock.h>
#include <linux/init.h>

View file

@ -4,7 +4,6 @@
#include <linux/config.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <asm/acpi.h>
#include <asm/arch_hooks.h>

View file

@ -27,7 +27,6 @@
#include <asm/voyager.h>
#include <asm/vic.h>
#include <linux/pm.h>
#include <linux/irq.h>
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>
#include <asm/i8253.h>

View file

@ -30,8 +30,6 @@
#include <asm/tlbflush.h>
#include <asm/arch_hooks.h>
#include <linux/irq.h>
/* TLB state -- visible externally, indexed physically */
DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };

View file

@ -31,8 +31,6 @@
#include <asm/mtrr.h>
#include <asm/msr.h>
#include <linux/irq.h>
#define THREAD_NAME "kvoyagerd"
/* external variables */

View file

@ -9,7 +9,7 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/errno.h>
#include <linux/oprofile.h>
#include <linux/rcupdate.h>

View file

@ -1,7 +1,6 @@
#include <linux/pci.h>
#include <linux/acpi.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/hw_irq.h>
#include <asm/numa.h>
#include "pci.h"

View file

@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/dmi.h>
#include <asm/io.h>
#include <asm/smp.h>

View file

@ -8,25 +8,8 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/spinlock.h>
#include <linux/poll.h>
#include <linux/delay.h>
#include <linux/sysrq.h>
#include <linux/proc_fs.h>
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/suspend.h>
#include <linux/acpi.h>
#include <asm/uaccess.h>
#include <asm/acpi.h>
#include <asm/tlbflush.h>
#include <asm/processor.h>
static struct saved_context saved_context;

View file

@ -24,7 +24,7 @@ aflags-$(CONFIG_ISA_M32R) += -DNO_FPU -Wa,-no-bitinst
CFLAGS += $(cflags-y)
AFLAGS += $(aflags-y)
CHECKFLAGS := $(CHECK) -D__m32r__
CHECKFLAGS += -D__m32r__ -D__BIG_ENDIAN__=1
head-y := arch/m32r/kernel/head.o arch/m32r/kernel/init_task.o

View file

@ -13,7 +13,7 @@
#include <asm/uaccess.h>
unsigned long
__generic_copy_to_user(void *to, const void *from, unsigned long n)
__generic_copy_to_user(void __user *to, const void *from, unsigned long n)
{
prefetch(from);
if (access_ok(VERIFY_WRITE, to, n))
@ -22,7 +22,7 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n)
}
unsigned long
__generic_copy_from_user(void *to, const void *from, unsigned long n)
__generic_copy_from_user(void *to, const void __user *from, unsigned long n)
{
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
@ -111,7 +111,7 @@ do { \
#endif /* CONFIG_ISA_DUAL_ISSUE */
long
__strncpy_from_user(char *dst, const char *src, long count)
__strncpy_from_user(char *dst, const char __user *src, long count)
{
long res;
__do_strncpy_from_user(dst, src, count, res);
@ -119,7 +119,7 @@ __strncpy_from_user(char *dst, const char *src, long count)
}
long
strncpy_from_user(char *dst, const char *src, long count)
strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
@ -222,7 +222,7 @@ do { \
#endif /* not CONFIG_ISA_DUAL_ISSUE */
unsigned long
clear_user(void *to, unsigned long n)
clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
__do_clear_user(to, n);
@ -230,7 +230,7 @@ clear_user(void *to, unsigned long n)
}
unsigned long
__clear_user(void *to, unsigned long n)
__clear_user(void __user *to, unsigned long n)
{
__do_clear_user(to, n);
return n;
@ -244,7 +244,7 @@ __clear_user(void *to, unsigned long n)
#ifdef CONFIG_ISA_DUAL_ISSUE
long strnlen_user(const char *s, long n)
long strnlen_user(const char __user *s, long n)
{
unsigned long mask = -__addr_ok(s);
unsigned long res;
@ -313,7 +313,7 @@ long strnlen_user(const char *s, long n)
#else /* not CONFIG_ISA_DUAL_ISSUE */
long strnlen_user(const char *s, long n)
long strnlen_user(const char __user *s, long n)
{
unsigned long mask = -__addr_ok(s);
unsigned long res;

View file

@ -45,9 +45,8 @@ static void dummy_perf(struct pt_regs *regs)
mtpmr(PMRN_PMGC0, pmgc0);
}
#elif CONFIG_6xx
#elif defined(CONFIG_6xx)
/* Ensure exceptions are disabled */
static void dummy_perf(struct pt_regs *regs)
{
unsigned int mmcr0 = mfspr(SPRN_MMCR0);

View file

@ -205,6 +205,7 @@ static void kexec_prepare_cpus(void)
continue;
while (paca[i].hw_cpu_id != -1) {
barrier();
if (!cpu_possible(i)) {
printk("kexec: cpu %d hw_cpu_id %d is not"
" possible, ignoring\n",

View file

@ -342,14 +342,13 @@ static void native_flush_hash_range(unsigned long number, int local)
hpte_t *hptep;
unsigned long hpte_v;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
unsigned long large;
unsigned long large = batch->large;
local_irq_save(flags);
j = 0;
for (i = 0; i < number; i++) {
va = batch->vaddr[j];
large = pte_huge(batch->pte[i]);
if (large)
vpn = va >> HPAGE_SHIFT;
else
@ -399,7 +398,7 @@ static void native_flush_hash_range(unsigned long number, int local)
asm volatile("ptesync":::"memory");
for (i = 0; i < j; i++)
__tlbie(batch->vaddr[i], 0);
__tlbie(batch->vaddr[i], large);
asm volatile("eieio; tlbsync; ptesync":::"memory");

View file

@ -141,12 +141,14 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
* up scanning and resetting referenced bits then our batch context
* will change mid stream.
*/
if (unlikely(i != 0 && mm != batch->mm)) {
if (i != 0 && (mm != batch->mm || batch->large != pte_huge(pte))) {
flush_tlb_pending();
i = 0;
}
if (i == 0)
if (i == 0) {
batch->mm = mm;
batch->large = pte_huge(pte);
}
if (addr < KERNELBASE) {
vsid = get_vsid(mm->context.id, addr);
WARN_ON(vsid == 0);

View file

@ -33,6 +33,14 @@ config DEBUG_BOOTMEM
depends on DEBUG_KERNEL
bool "Debug BOOTMEM initialization"
config DEBUG_PAGEALLOC
bool "Page alloc debugging"
depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND
help
Unmap pages from the kernel linear mapping after free_pages().
This results in a large slowdown, but helps to find certain types
of memory corruptions.
config MCOUNT
bool
depends on STACK_DEBUG

View file

@ -135,6 +135,28 @@ void __init device_scan(void)
cpu_data(0).clock_tick = prom_getintdefault(cpu_node,
"clock-frequency",
0);
cpu_data(0).dcache_size = prom_getintdefault(cpu_node,
"dcache-size",
16 * 1024);
cpu_data(0).dcache_line_size =
prom_getintdefault(cpu_node, "dcache-line-size", 32);
cpu_data(0).icache_size = prom_getintdefault(cpu_node,
"icache-size",
16 * 1024);
cpu_data(0).icache_line_size =
prom_getintdefault(cpu_node, "icache-line-size", 32);
cpu_data(0).ecache_size = prom_getintdefault(cpu_node,
"ecache-size",
4 * 1024 * 1024);
cpu_data(0).ecache_line_size =
prom_getintdefault(cpu_node, "ecache-line-size", 64);
printk("CPU[0]: Caches "
"D[sz(%d):line_sz(%d)] "
"I[sz(%d):line_sz(%d)] "
"E[sz(%d):line_sz(%d)]\n",
cpu_data(0).dcache_size, cpu_data(0).dcache_line_size,
cpu_data(0).icache_size, cpu_data(0).icache_line_size,
cpu_data(0).ecache_size, cpu_data(0).ecache_line_size);
}
#endif

View file

@ -9,17 +9,7 @@
#include <asm/pgtable.h>
#include <asm/mmu.h>
#if PAGE_SHIFT == 13
#define SZ_BITS _PAGE_SZ8K
#elif PAGE_SHIFT == 16
#define SZ_BITS _PAGE_SZ64K
#elif PAGE_SHIFT == 19
#define SZ_BITS _PAGE_SZ512K
#elif PAGE_SHIFT == 22
#define SZ_BITS _PAGE_SZ4MB
#endif
#define VALID_SZ_BITS (_PAGE_VALID | SZ_BITS)
#define VALID_SZ_BITS (_PAGE_VALID | _PAGE_SZBITS)
#define VPTE_BITS (_PAGE_CP | _PAGE_CV | _PAGE_P )
#define VPTE_SHIFT (PAGE_SHIFT - 3)
@ -163,7 +153,6 @@ sparc64_vpte_continue:
stxa %g4, [%g1 + %g1] ASI_DMMU ! Restore previous TAG_ACCESS
retry ! Load PTE once again
#undef SZ_BITS
#undef VALID_SZ_BITS
#undef VPTE_SHIFT
#undef VPTE_BITS

View file

@ -71,7 +71,7 @@
from_tl1_trap:
rdpr %tl, %g5 ! For TL==3 test
CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
be,pn %xcc, 3f ! Yep, special processing
be,pn %xcc, kvmap ! Yep, special processing
CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
cmp %g5, 4 ! Last trap level?
be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
@ -83,9 +83,9 @@ from_tl1_trap:
nop ! Delay-slot
9: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
retry ! Trap return
3: brlz,pt %g4, 9b ! Kernel virtual map?
xor %g2, %g4, %g5 ! Finish bit twiddles
ba,a,pt %xcc, kvmap ! Yep, go check for obp/vmalloc
nop
nop
nop
/* DTLB ** ICACHE line 3: winfixups+real_faults */
longpath:

View file

@ -30,159 +30,6 @@
.text
.align 32
.globl sparc64_vpte_patchme1
.globl sparc64_vpte_patchme2
/*
* On a second level vpte miss, check whether the original fault is to the OBP
* range (note that this is only possible for instruction miss, data misses to
* obp range do not use vpte). If so, go back directly to the faulting address.
* This is because we want to read the tpc, otherwise we have no way of knowing
* the 8k aligned faulting address if we are using >8k kernel pagesize. This
* also ensures no vpte range addresses are dropped into tlb while obp is
* executing (see inherit_locked_prom_mappings() rant).
*/
sparc64_vpte_nucleus:
/* Note that kvmap below has verified that the address is
* in the range MODULES_VADDR --> VMALLOC_END already. So
* here we need only check if it is an OBP address or not.
*/
sethi %hi(LOW_OBP_ADDRESS), %g5
cmp %g4, %g5
blu,pn %xcc, sparc64_vpte_patchme1
mov 0x1, %g5
sllx %g5, 32, %g5
cmp %g4, %g5
blu,pn %xcc, obp_iaddr_patch
nop
/* These two instructions are patched by paginig_init(). */
sparc64_vpte_patchme1:
sethi %hi(0), %g5
sparc64_vpte_patchme2:
or %g5, %lo(0), %g5
/* With kernel PGD in %g5, branch back into dtlb_backend. */
ba,pt %xcc, sparc64_kpte_continue
andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */
vpte_noent:
/* Restore previous TAG_ACCESS, %g5 is zero, and we will
* skip over the trap instruction so that the top level
* TLB miss handler will thing this %g5 value is just an
* invalid PTE, thus branching to full fault processing.
*/
mov TLB_SFSR, %g1
stxa %g4, [%g1 + %g1] ASI_DMMU
done
.globl obp_iaddr_patch
obp_iaddr_patch:
/* These two instructions patched by inherit_prom_mappings(). */
sethi %hi(0), %g5
or %g5, %lo(0), %g5
/* Behave as if we are at TL0. */
wrpr %g0, 1, %tl
rdpr %tpc, %g4 /* Find original faulting iaddr */
srlx %g4, 13, %g4 /* Throw out context bits */
sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */
/* Restore previous TAG_ACCESS. */
mov TLB_SFSR, %g1
stxa %g4, [%g1 + %g1] ASI_IMMU
/* Get PMD offset. */
srlx %g4, 23, %g6
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6
/* Load PMD, is it valid? */
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g5, 11, %g5
/* Get PTE offset. */
srlx %g4, 13, %g6
and %g6, 0x3ff, %g6
sllx %g6, 3, %g6
/* Load PTE. */
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brgez,pn %g5, longpath
nop
/* TLB load and return from trap. */
stxa %g5, [%g0] ASI_ITLB_DATA_IN
retry
.globl obp_daddr_patch
obp_daddr_patch:
/* These two instructions patched by inherit_prom_mappings(). */
sethi %hi(0), %g5
or %g5, %lo(0), %g5
/* Get PMD offset. */
srlx %g4, 23, %g6
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6
/* Load PMD, is it valid? */
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g5, 11, %g5
/* Get PTE offset. */
srlx %g4, 13, %g6
and %g6, 0x3ff, %g6
sllx %g6, 3, %g6
/* Load PTE. */
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brgez,pn %g5, longpath
nop
/* TLB load and return from trap. */
stxa %g5, [%g0] ASI_DTLB_DATA_IN
retry
/*
* On a first level data miss, check whether this is to the OBP range (note
* that such accesses can be made by prom, as well as by kernel using
* prom_getproperty on "address"), and if so, do not use vpte access ...
* rather, use information saved during inherit_prom_mappings() using 8k
* pagesize.
*/
.align 32
kvmap:
sethi %hi(MODULES_VADDR), %g5
cmp %g4, %g5
blu,pn %xcc, longpath
mov (VMALLOC_END >> 24), %g5
sllx %g5, 24, %g5
cmp %g4, %g5
bgeu,pn %xcc, longpath
nop
kvmap_check_obp:
sethi %hi(LOW_OBP_ADDRESS), %g5
cmp %g4, %g5
blu,pn %xcc, kvmap_vmalloc_addr
mov 0x1, %g5
sllx %g5, 32, %g5
cmp %g4, %g5
blu,pn %xcc, obp_daddr_patch
nop
kvmap_vmalloc_addr:
/* If we get here, a vmalloc addr was accessed, load kernel VPTE. */
ldxa [%g3 + %g6] ASI_N, %g5
brgez,pn %g5, longpath
nop
/* PTE is valid, load into TLB and return from trap. */
stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
retry
/* This is trivial with the new code... */
.globl do_fpdis
do_fpdis:
@ -525,14 +372,13 @@ cheetah_plus_patch_fpdis:
*
* DATA 0: [low 32-bits] Address of function to call, jmp to this
* [high 32-bits] MMU Context Argument 0, place in %g5
* DATA 1: Address Argument 1, place in %g6
* DATA 1: Address Argument 1, place in %g1
* DATA 2: Address Argument 2, place in %g7
*
* With this method we can do most of the cross-call tlb/cache
* flushing very quickly.
*
* Current CPU's IRQ worklist table is locked into %g1,
* don't touch.
* Current CPU's IRQ worklist table is locked into %g6, don't touch.
*/
.text
.align 32
@ -1006,13 +852,14 @@ cheetah_plus_dcpe_trap_vector:
nop
do_cheetah_plus_data_parity:
ba,pt %xcc, etrap
rdpr %pil, %g2
wrpr %g0, 15, %pil
ba,pt %xcc, etrap_irq
rd %pc, %g7
mov 0x0, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
clr %l6
ba,a,pt %xcc, rtrap_irq
cheetah_plus_dcpe_trap_vector_tl1:
membar #Sync
@ -1036,13 +883,14 @@ cheetah_plus_icpe_trap_vector:
nop
do_cheetah_plus_insn_parity:
ba,pt %xcc, etrap
rdpr %pil, %g2
wrpr %g0, 15, %pil
ba,pt %xcc, etrap_irq
rd %pc, %g7
mov 0x1, %o0
call cheetah_plus_parity_error
add %sp, PTREGS_OFF, %o1
ba,pt %xcc, rtrap
clr %l6
ba,a,pt %xcc, rtrap_irq
cheetah_plus_icpe_trap_vector_tl1:
membar #Sync
@ -1075,6 +923,10 @@ do_dcpe_tl1:
nop
wrpr %g1, %tl ! Restore original trap level
do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
sethi %hi(dcache_parity_tl1_occurred), %g2
lduw [%g2 + %lo(dcache_parity_tl1_occurred)], %g1
add %g1, 1, %g1
stw %g1, [%g2 + %lo(dcache_parity_tl1_occurred)]
/* Reset D-cache parity */
sethi %hi(1 << 16), %g1 ! D-cache size
mov (1 << 5), %g2 ! D-cache line size
@ -1121,6 +973,10 @@ do_icpe_tl1:
nop
wrpr %g1, %tl ! Restore original trap level
do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
sethi %hi(icache_parity_tl1_occurred), %g2
lduw [%g2 + %lo(icache_parity_tl1_occurred)], %g1
add %g1, 1, %g1
stw %g1, [%g2 + %lo(icache_parity_tl1_occurred)]
/* Flush I-cache */
sethi %hi(1 << 15), %g1 ! I-cache size
mov (1 << 5), %g2 ! I-cache line size

View file

@ -80,15 +80,165 @@ sparc_ramdisk_image64:
.xword 0
.word _end
/* We must be careful, 32-bit OpenBOOT will get confused if it
* tries to save away a register window to a 64-bit kernel
* stack address. Flush all windows, disable interrupts,
* remap if necessary, jump onto kernel trap table, then kernel
* stack, or else we die.
*
* PROM entry point is on %o4
*/
/* PROM cif handler code address is in %o4. */
sparc64_boot:
1: rd %pc, %g7
set 1b, %g1
cmp %g1, %g7
be,pn %xcc, sparc64_boot_after_remap
mov %o4, %l7
/* We need to remap the kernel. Use position independant
* code to remap us to KERNBASE.
*
* SILO can invoke us with 32-bit address masking enabled,
* so make sure that's clear.
*/
rdpr %pstate, %g1
andn %g1, PSTATE_AM, %g1
wrpr %g1, 0x0, %pstate
ba,a,pt %xcc, 1f
.globl prom_finddev_name, prom_chosen_path
.globl prom_getprop_name, prom_mmu_name
.globl prom_callmethod_name, prom_translate_name
.globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
.globl prom_boot_mapped_pc, prom_boot_mapping_mode
.globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
prom_finddev_name:
.asciz "finddevice"
prom_chosen_path:
.asciz "/chosen"
prom_getprop_name:
.asciz "getprop"
prom_mmu_name:
.asciz "mmu"
prom_callmethod_name:
.asciz "call-method"
prom_translate_name:
.asciz "translate"
prom_map_name:
.asciz "map"
prom_unmap_name:
.asciz "unmap"
.align 4
prom_mmu_ihandle_cache:
.word 0
prom_boot_mapped_pc:
.word 0
prom_boot_mapping_mode:
.word 0
.align 8
prom_boot_mapping_phys_high:
.xword 0
prom_boot_mapping_phys_low:
.xword 0
1:
rd %pc, %l0
mov (1b - prom_finddev_name), %l1
mov (1b - prom_chosen_path), %l2
mov (1b - prom_boot_mapped_pc), %l3
sub %l0, %l1, %l1
sub %l0, %l2, %l2
sub %l0, %l3, %l3
stw %l0, [%l3]
sub %sp, (192 + 128), %sp
/* chosen_node = prom_finddevice("/chosen") */
stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice"
mov 1, %l3
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/chosen"
stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1
call %l7
add %sp, (2047 + 128), %o0 ! argument array
ldx [%sp + 2047 + 128 + 0x20], %l4 ! chosen device node
mov (1b - prom_getprop_name), %l1
mov (1b - prom_mmu_name), %l2
mov (1b - prom_mmu_ihandle_cache), %l5
sub %l0, %l1, %l1
sub %l0, %l2, %l2
sub %l0, %l5, %l5
/* prom_mmu_ihandle_cache = prom_getint(chosen_node, "mmu") */
stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop"
mov 4, %l3
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4
mov 1, %l3
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, chosen_node
stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "mmu"
stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_mmu_ihandle_cache
mov 4, %l3
stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, sizeof(arg3)
stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1
call %l7
add %sp, (2047 + 128), %o0 ! argument array
mov (1b - prom_callmethod_name), %l1
mov (1b - prom_translate_name), %l2
sub %l0, %l1, %l1
sub %l0, %l2, %l2
lduw [%l5], %l5 ! prom_mmu_ihandle_cache
stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "call-method"
mov 3, %l3
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 3
mov 5, %l3
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5
stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate"
stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache
srlx %l0, 22, %l3
sllx %l3, 22, %l3
stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC
stx %g0, [%sp + 2047 + 128 + 0x30] ! res1
stx %g0, [%sp + 2047 + 128 + 0x38] ! res2
stx %g0, [%sp + 2047 + 128 + 0x40] ! res3
stx %g0, [%sp + 2047 + 128 + 0x48] ! res4
stx %g0, [%sp + 2047 + 128 + 0x50] ! res5
call %l7
add %sp, (2047 + 128), %o0 ! argument array
ldx [%sp + 2047 + 128 + 0x40], %l1 ! translation mode
mov (1b - prom_boot_mapping_mode), %l4
sub %l0, %l4, %l4
stw %l1, [%l4]
mov (1b - prom_boot_mapping_phys_high), %l4
sub %l0, %l4, %l4
ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high
stx %l2, [%l4 + 0x0]
ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
stx %l3, [%l4 + 0x8]
/* Leave service as-is, "call-method" */
mov 7, %l3
stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 7
mov 1, %l3
stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
mov (1b - prom_map_name), %l3
sub %l0, %l3, %l3
stx %l3, [%sp + 2047 + 128 + 0x18] ! arg1: "map"
/* Leave arg2 as-is, prom_mmu_ihandle_cache */
mov -1, %l3
stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: mode (-1 default)
sethi %hi(8 * 1024 * 1024), %l3
stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4: size (8MB)
sethi %hi(KERNBASE), %l3
stx %l3, [%sp + 2047 + 128 + 0x38] ! arg5: vaddr (KERNBASE)
stx %g0, [%sp + 2047 + 128 + 0x40] ! arg6: empty
mov (1b - prom_boot_mapping_phys_low), %l3
sub %l0, %l3, %l3
ldx [%l3], %l3
stx %l3, [%sp + 2047 + 128 + 0x48] ! arg7: phys addr
call %l7
add %sp, (2047 + 128), %o0 ! argument array
add %sp, (192 + 128), %sp
sparc64_boot_after_remap:
BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
ba,pt %xcc, spitfire_boot
@ -125,185 +275,7 @@ cheetah_generic_boot:
stxa %g0, [%g3] ASI_IMMU
membar #Sync
wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
wr %g0, 0, %fprs
/* Just like for Spitfire, we probe itlb-2 for a mapping which
* matches our current %pc. We take the physical address in
* that mapping and use it to make our own.
*/
/* %g5 holds the tlb data */
sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
sllx %g5, 32, %g5
or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
/* Put PADDR tlb data mask into %g3. */
sethi %uhi(_PAGE_PADDR), %g3
or %g3, %ulo(_PAGE_PADDR), %g3
sllx %g3, 32, %g3
sethi %hi(_PAGE_PADDR), %g7
or %g7, %lo(_PAGE_PADDR), %g7
or %g3, %g7, %g3
set 2 << 16, %l0 /* TLB entry walker. */
set 0x1fff, %l2 /* Page mask. */
rd %pc, %l3
andn %l3, %l2, %g2 /* vaddr comparator */
1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
cmp %g1, %g2
be,pn %xcc, cheetah_got_tlbentry
nop
and %l0, (127 << 3), %g1
cmp %g1, (127 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
/* Search the small TLB. OBP never maps us like that but
* newer SILO can.
*/
clr %l0
1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
cmp %g1, %g2
be,pn %xcc, cheetah_got_tlbentry
nop
cmp %l0, (15 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
/* BUG() if we get here... */
ta 0x5
cheetah_got_tlbentry:
ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g0
ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
membar #Sync
and %g1, %g3, %g1
set 0x5fff, %l0
andn %g1, %l0, %g1
or %g5, %g1, %g5
/* Clear out any KERNBASE area entries. */
set 2 << 16, %l0
sethi %hi(KERNBASE), %g3
sethi %hi(KERNBASE<<1), %g7
mov TLB_TAG_ACCESS, %l7
/* First, check ITLB */
1: ldxa [%l0] ASI_ITLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
cmp %g1, %g3
blu,pn %xcc, 2f
cmp %g1, %g7
bgeu,pn %xcc, 2f
nop
stxa %g0, [%l7] ASI_IMMU
membar #Sync
stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
membar #Sync
2: and %l0, (127 << 3), %g1
cmp %g1, (127 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
/* Next, check DTLB */
set 2 << 16, %l0
1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
cmp %g1, %g3
blu,pn %xcc, 2f
cmp %g1, %g7
bgeu,pn %xcc, 2f
nop
stxa %g0, [%l7] ASI_DMMU
membar #Sync
stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
membar #Sync
2: and %l0, (511 << 3), %g1
cmp %g1, (511 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
/* On Cheetah+, have to check second DTLB. */
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,l0,2f)
ba,pt %xcc, 9f
nop
2: set 3 << 16, %l0
1: ldxa [%l0] ASI_DTLB_TAG_READ, %g1
membar #Sync
andn %g1, %l2, %g1
cmp %g1, %g3
blu,pn %xcc, 2f
cmp %g1, %g7
bgeu,pn %xcc, 2f
nop
stxa %g0, [%l7] ASI_DMMU
membar #Sync
stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
membar #Sync
2: and %l0, (511 << 3), %g1
cmp %g1, (511 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
9:
/* Now lock the TTE we created into ITLB-0 and DTLB-0,
* entry 15 (and maybe 14 too).
*/
sethi %hi(KERNBASE), %g3
set (0 << 16) | (15 << 3), %g7
stxa %g3, [%l7] ASI_DMMU
membar #Sync
stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
membar #Sync
stxa %g3, [%l7] ASI_IMMU
membar #Sync
stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
membar #Sync
flush %g3
membar #Sync
sethi %hi(_end), %g3 /* Check for bigkernel case */
or %g3, %lo(_end), %g3
srl %g3, 23, %g3 /* Check if _end > 8M */
brz,pt %g3, 1f
sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
sethi %hi(0x400000), %g3
or %g3, %lo(0x400000), %g3
add %g5, %g3, %g5 /* New tte data */
andn %g5, (_PAGE_G), %g5
sethi %hi(KERNBASE+0x400000), %g3
or %g3, %lo(KERNBASE+0x400000), %g3
set (0 << 16) | (14 << 3), %g7
stxa %g3, [%l7] ASI_DMMU
membar #Sync
stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
membar #Sync
stxa %g3, [%l7] ASI_IMMU
membar #Sync
stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
membar #Sync
flush %g3
membar #Sync
sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
ba,pt %xcc, 1f
nop
1: set sun4u_init, %g2
jmpl %g2 + %g0, %g0
nop
ba,a,pt %xcc, jump_to_sun4u_init
spitfire_boot:
/* Typically PROM has already enabled both MMU's and both on-chip
@ -313,6 +285,7 @@ spitfire_boot:
stxa %g1, [%g0] ASI_LSU_CONTROL
membar #Sync
jump_to_sun4u_init:
/*
* Make sure we are in privileged mode, have address masking,
* using the ordinary globals and have enabled floating
@ -324,151 +297,6 @@ spitfire_boot:
wrpr %g0, (PSTATE_PRIV|PSTATE_PEF|PSTATE_IE), %pstate
wr %g0, 0, %fprs
spitfire_create_mappings:
/* %g5 holds the tlb data */
sethi %uhi(_PAGE_VALID | _PAGE_SZ4MB), %g5
sllx %g5, 32, %g5
or %g5, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W | _PAGE_G), %g5
/* Base of physical memory cannot reliably be assumed to be
* at 0x0! Figure out where it happens to be. -DaveM
*/
/* Put PADDR tlb data mask into %g3. */
sethi %uhi(_PAGE_PADDR_SF), %g3
or %g3, %ulo(_PAGE_PADDR_SF), %g3
sllx %g3, 32, %g3
sethi %hi(_PAGE_PADDR_SF), %g7
or %g7, %lo(_PAGE_PADDR_SF), %g7
or %g3, %g7, %g3
/* Walk through entire ITLB, looking for entry which maps
* our %pc currently, stick PADDR from there into %g5 tlb data.
*/
clr %l0 /* TLB entry walker. */
set 0x1fff, %l2 /* Page mask. */
rd %pc, %l3
andn %l3, %l2, %g2 /* vaddr comparator */
1:
/* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
ldxa [%l0] ASI_ITLB_TAG_READ, %g1
nop
nop
nop
andn %g1, %l2, %g1 /* Get vaddr */
cmp %g1, %g2
be,a,pn %xcc, spitfire_got_tlbentry
ldxa [%l0] ASI_ITLB_DATA_ACCESS, %g1
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
/* BUG() if we get here... */
ta 0x5
spitfire_got_tlbentry:
/* Nops here again, perhaps Cheetah/Blackbird are better behaved... */
nop
nop
nop
and %g1, %g3, %g1 /* Mask to just get paddr bits. */
set 0x5fff, %l3 /* Mask offset to get phys base. */
andn %g1, %l3, %g1
/* NOTE: We hold on to %g1 paddr base as we need it below to lock
* NOTE: the PROM cif code into the TLB.
*/
or %g5, %g1, %g5 /* Or it into TAG being built. */
clr %l0 /* TLB entry walker. */
sethi %hi(KERNBASE), %g3 /* 4M lower limit */
sethi %hi(KERNBASE<<1), %g7 /* 8M upper limit */
mov TLB_TAG_ACCESS, %l7
1:
/* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
ldxa [%l0] ASI_ITLB_TAG_READ, %g1
nop
nop
nop
andn %g1, %l2, %g1 /* Get vaddr */
cmp %g1, %g3
blu,pn %xcc, 2f
cmp %g1, %g7
bgeu,pn %xcc, 2f
nop
stxa %g0, [%l7] ASI_IMMU
stxa %g0, [%l0] ASI_ITLB_DATA_ACCESS
membar #Sync
2:
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
nop; nop; nop
clr %l0 /* TLB entry walker. */
1:
/* Yes, the nops seem to be necessary for now, don't ask me why. -DaveM */
ldxa [%l0] ASI_DTLB_TAG_READ, %g1
nop
nop
nop
andn %g1, %l2, %g1 /* Get vaddr */
cmp %g1, %g3
blu,pn %xcc, 2f
cmp %g1, %g7
bgeu,pn %xcc, 2f
nop
stxa %g0, [%l7] ASI_DMMU
stxa %g0, [%l0] ASI_DTLB_DATA_ACCESS
membar #Sync
2:
cmp %l0, (63 << 3)
blu,pt %xcc, 1b
add %l0, (1 << 3), %l0
nop; nop; nop
/* PROM never puts any TLB entries into the MMU with the lock bit
* set. So we gladly use tlb entry 63 for KERNBASE. And maybe 62 too.
*/
sethi %hi(KERNBASE), %g3
mov (63 << 3), %g7
stxa %g3, [%l7] ASI_DMMU /* KERNBASE into TLB TAG */
stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS /* TTE into TLB DATA */
membar #Sync
stxa %g3, [%l7] ASI_IMMU /* KERNBASE into TLB TAG */
stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS /* TTE into TLB DATA */
membar #Sync
flush %g3
membar #Sync
sethi %hi(_end), %g3 /* Check for bigkernel case */
or %g3, %lo(_end), %g3
srl %g3, 23, %g3 /* Check if _end > 8M */
brz,pt %g3, 2f
sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
sethi %hi(0x400000), %g3
or %g3, %lo(0x400000), %g3
add %g5, %g3, %g5 /* New tte data */
andn %g5, (_PAGE_G), %g5
sethi %hi(KERNBASE+0x400000), %g3
or %g3, %lo(KERNBASE+0x400000), %g3
mov (62 << 3), %g7
stxa %g3, [%l7] ASI_DMMU
stxa %g5, [%g7] ASI_DTLB_DATA_ACCESS
membar #Sync
stxa %g3, [%l7] ASI_IMMU
stxa %g5, [%g7] ASI_ITLB_DATA_ACCESS
membar #Sync
flush %g3
membar #Sync
sethi %hi(KERNBASE), %g3 /* Restore for fixup code below */
2: ba,pt %xcc, 1f
nop
1:
set sun4u_init, %g2
jmpl %g2 + %g0, %g0
nop
@ -483,38 +311,12 @@ sun4u_init:
stxa %g0, [%g7] ASI_DMMU
membar #Sync
/* We are now safely (we hope) in Nucleus context (0), rewrite
* the KERNBASE TTE's so they no longer have the global bit set.
* Don't forget to setup TAG_ACCESS first 8-)
*/
mov TLB_TAG_ACCESS, %g2
stxa %g3, [%g2] ASI_IMMU
stxa %g3, [%g2] ASI_DMMU
membar #Sync
BRANCH_IF_ANY_CHEETAH(g1,g7,cheetah_tlb_fixup)
ba,pt %xcc, spitfire_tlb_fixup
nop
cheetah_tlb_fixup:
set (0 << 16) | (15 << 3), %g7
ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g0
ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
andn %g1, (_PAGE_G), %g1
stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
membar #Sync
ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g0
ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
andn %g1, (_PAGE_G), %g1
stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
membar #Sync
/* Kill instruction prefetch queues. */
flush %g3
membar #Sync
mov 2, %g2 /* Set TLB type to cheetah+. */
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,1f)
@ -551,21 +353,6 @@ cheetah_tlb_fixup:
nop
spitfire_tlb_fixup:
mov (63 << 3), %g7
ldxa [%g7] ASI_ITLB_DATA_ACCESS, %g1
andn %g1, (_PAGE_G), %g1
stxa %g1, [%g7] ASI_ITLB_DATA_ACCESS
membar #Sync
ldxa [%g7] ASI_DTLB_DATA_ACCESS, %g1
andn %g1, (_PAGE_G), %g1
stxa %g1, [%g7] ASI_DTLB_DATA_ACCESS
membar #Sync
/* Kill instruction prefetch queues. */
flush %g3
membar #Sync
/* Set TLB type to spitfire. */
mov 0, %g2
sethi %hi(tlb_type), %g1
@ -578,24 +365,6 @@ tlb_fixup_done:
mov %sp, %l6
mov %o4, %l7
#if 0 /* We don't do it like this anymore, but for historical hack value
* I leave this snippet here to show how crazy we can be sometimes. 8-)
*/
/* Setup "Linux Current Register", thanks Sun 8-) */
wr %g0, 0x1, %pcr
/* Blackbird errata workaround. See commentary in
* smp.c:smp_percpu_timer_interrupt() for more
* information.
*/
ba,pt %xcc, 99f
nop
.align 64
99: wr %g6, %g0, %pic
rd %pic, %g0
#endif
wr %g0, ASI_P, %asi
mov 1, %g1
sllx %g1, THREAD_SHIFT, %g1
@ -756,12 +525,7 @@ bootup_user_stack_end:
#include "ttable.S"
#include "systbls.S"
.align 1024
.globl swapper_pg_dir
swapper_pg_dir:
.word 0
#include "ktlb.S"
#include "etrap.S"
#include "rtrap.S"
#include "winfixup.S"

198
arch/sparc64/kernel/ktlb.S Normal file
View file

@ -0,0 +1,198 @@
/* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling.
*
* Copyright (C) 1995, 1997, 2005 David S. Miller <davem@davemloft.net>
* Copyright (C) 1996 Eddie C. Dost (ecd@brainaid.de)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1996,98,99 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
#include <linux/config.h>
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/page.h>
#include <asm/pgtable.h>
.text
.align 32
/*
* On a second level vpte miss, check whether the original fault is to the OBP
* range (note that this is only possible for instruction miss, data misses to
* obp range do not use vpte). If so, go back directly to the faulting address.
* This is because we want to read the tpc, otherwise we have no way of knowing
* the 8k aligned faulting address if we are using >8k kernel pagesize. This
* also ensures no vpte range addresses are dropped into tlb while obp is
* executing (see inherit_locked_prom_mappings() rant).
*/
sparc64_vpte_nucleus:
/* Note that kvmap below has verified that the address is
* in the range MODULES_VADDR --> VMALLOC_END already. So
* here we need only check if it is an OBP address or not.
*/
sethi %hi(LOW_OBP_ADDRESS), %g5
cmp %g4, %g5
blu,pn %xcc, kern_vpte
mov 0x1, %g5
sllx %g5, 32, %g5
cmp %g4, %g5
blu,pn %xcc, vpte_insn_obp
nop
/* These two instructions are patched by paginig_init(). */
kern_vpte:
sethi %hi(swapper_pgd_zero), %g5
lduw [%g5 + %lo(swapper_pgd_zero)], %g5
/* With kernel PGD in %g5, branch back into dtlb_backend. */
ba,pt %xcc, sparc64_kpte_continue
andn %g1, 0x3, %g1 /* Finish PMD offset adjustment. */
vpte_noent:
/* Restore previous TAG_ACCESS, %g5 is zero, and we will
* skip over the trap instruction so that the top level
* TLB miss handler will thing this %g5 value is just an
* invalid PTE, thus branching to full fault processing.
*/
mov TLB_SFSR, %g1
stxa %g4, [%g1 + %g1] ASI_DMMU
done
vpte_insn_obp:
sethi %hi(prom_pmd_phys), %g5
ldx [%g5 + %lo(prom_pmd_phys)], %g5
/* Behave as if we are at TL0. */
wrpr %g0, 1, %tl
rdpr %tpc, %g4 /* Find original faulting iaddr */
srlx %g4, 13, %g4 /* Throw out context bits */
sllx %g4, 13, %g4 /* g4 has vpn + ctx0 now */
/* Restore previous TAG_ACCESS. */
mov TLB_SFSR, %g1
stxa %g4, [%g1 + %g1] ASI_IMMU
/* Get PMD offset. */
srlx %g4, 23, %g6
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6
/* Load PMD, is it valid? */
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g5, 11, %g5
/* Get PTE offset. */
srlx %g4, 13, %g6
and %g6, 0x3ff, %g6
sllx %g6, 3, %g6
/* Load PTE. */
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brgez,pn %g5, longpath
nop
/* TLB load and return from trap. */
stxa %g5, [%g0] ASI_ITLB_DATA_IN
retry
kvmap_do_obp:
sethi %hi(prom_pmd_phys), %g5
ldx [%g5 + %lo(prom_pmd_phys)], %g5
/* Get PMD offset. */
srlx %g4, 23, %g6
and %g6, 0x7ff, %g6
sllx %g6, 2, %g6
/* Load PMD, is it valid? */
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g5, 11, %g5
/* Get PTE offset. */
srlx %g4, 13, %g6
and %g6, 0x3ff, %g6
sllx %g6, 3, %g6
/* Load PTE. */
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brgez,pn %g5, longpath
nop
/* TLB load and return from trap. */
stxa %g5, [%g0] ASI_DTLB_DATA_IN
retry
/*
* On a first level data miss, check whether this is to the OBP range (note
* that such accesses can be made by prom, as well as by kernel using
* prom_getproperty on "address"), and if so, do not use vpte access ...
* rather, use information saved during inherit_prom_mappings() using 8k
* pagesize.
*/
.align 32
kvmap:
brgez,pn %g4, kvmap_nonlinear
nop
#ifdef CONFIG_DEBUG_PAGEALLOC
.globl kvmap_linear_patch
kvmap_linear_patch:
#endif
ba,pt %xcc, kvmap_load
xor %g2, %g4, %g5
#ifdef CONFIG_DEBUG_PAGEALLOC
sethi %hi(swapper_pg_dir), %g5
or %g5, %lo(swapper_pg_dir), %g5
sllx %g4, 64 - (PGDIR_SHIFT + PGDIR_BITS), %g6
srlx %g6, 64 - PAGE_SHIFT, %g6
andn %g6, 0x3, %g6
lduw [%g5 + %g6], %g5
brz,pn %g5, longpath
sllx %g4, 64 - (PMD_SHIFT + PMD_BITS), %g6
srlx %g6, 64 - PAGE_SHIFT, %g6
sllx %g5, 11, %g5
andn %g6, 0x3, %g6
lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
sllx %g4, 64 - PMD_SHIFT, %g6
srlx %g6, 64 - PAGE_SHIFT, %g6
sllx %g5, 11, %g5
andn %g6, 0x7, %g6
ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
brz,pn %g5, longpath
nop
ba,a,pt %xcc, kvmap_load
#endif
kvmap_nonlinear:
sethi %hi(MODULES_VADDR), %g5
cmp %g4, %g5
blu,pn %xcc, longpath
mov (VMALLOC_END >> 24), %g5
sllx %g5, 24, %g5
cmp %g4, %g5
bgeu,pn %xcc, longpath
nop
kvmap_check_obp:
sethi %hi(LOW_OBP_ADDRESS), %g5
cmp %g4, %g5
blu,pn %xcc, kvmap_vmalloc_addr
mov 0x1, %g5
sllx %g5, 32, %g5
cmp %g4, %g5
blu,pn %xcc, kvmap_do_obp
nop
kvmap_vmalloc_addr:
/* If we get here, a vmalloc addr was accessed, load kernel VPTE. */
ldxa [%g3 + %g6] ASI_N, %g5
brgez,pn %g5, longpath
nop
kvmap_load:
/* PTE is valid, load into TLB and return from trap. */
stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
retry

View file

@ -330,7 +330,7 @@ static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino)
static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
{
unsigned long sync_reg = (unsigned long) _arg2;
u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO);
u64 mask = 1UL << (__irq_ino(__irq(bucket)) & IMAP_INO);
u64 val;
int limit;

View file

@ -496,7 +496,6 @@ extern void paging_init(void);
void __init setup_arch(char **cmdline_p)
{
unsigned long highest_paddr;
int i;
/* Initialize PROM console and command line. */
@ -519,11 +518,7 @@ void __init setup_arch(char **cmdline_p)
idprom_init();
(void) prom_probe_memory();
/* In paging_init() we tip off this value to see if we need
* to change init_mm.pgd to point to the real alias mapping.
*/
phys_base = 0xffffffffffffffffUL;
highest_paddr = 0UL;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
unsigned long top;
@ -531,25 +526,10 @@ void __init setup_arch(char **cmdline_p)
phys_base = sp_banks[i].base_addr;
top = sp_banks[i].base_addr +
sp_banks[i].num_bytes;
if (highest_paddr < top)
highest_paddr = top;
}
pfn_base = phys_base >> PAGE_SHIFT;
switch (tlb_type) {
default:
case spitfire:
kern_base = spitfire_get_itlb_data(sparc64_highest_locked_tlbent());
kern_base &= _PAGE_PADDR_SF;
break;
case cheetah:
case cheetah_plus:
kern_base = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());
kern_base &= _PAGE_PADDR;
break;
};
kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
kern_size = (unsigned long)&_end - (unsigned long)KERNBASE;
if (!root_flags)
@ -625,6 +605,9 @@ extern void smp_info(struct seq_file *);
extern void smp_bogo(struct seq_file *);
extern void mmu_info(struct seq_file *);
unsigned int dcache_parity_tl1_occurred;
unsigned int icache_parity_tl1_occurred;
static int show_cpuinfo(struct seq_file *m, void *__unused)
{
seq_printf(m,
@ -635,6 +618,8 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
"type\t\t: sun4u\n"
"ncpus probed\t: %ld\n"
"ncpus active\t: %ld\n"
"D$ parity tl1\t: %u\n"
"I$ parity tl1\t: %u\n"
#ifndef CONFIG_SMP
"Cpu0Bogo\t: %lu.%02lu\n"
"Cpu0ClkTck\t: %016lx\n"
@ -647,7 +632,9 @@ static int show_cpuinfo(struct seq_file *m, void *__unused)
(prom_prev >> 8) & 0xff,
prom_prev & 0xff,
(long)num_possible_cpus(),
(long)num_online_cpus()
(long)num_online_cpus(),
dcache_parity_tl1_occurred,
icache_parity_tl1_occurred
#ifndef CONFIG_SMP
, cpu_data(0).udelay_val/(500000/HZ),
(cpu_data(0).udelay_val/(5000/HZ)) % 100,

View file

@ -93,6 +93,27 @@ void __init smp_store_cpu_info(int id)
cpu_data(id).pte_cache[1] = NULL;
cpu_data(id).pgd_cache = NULL;
cpu_data(id).idle_volume = 1;
cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size",
16 * 1024);
cpu_data(id).dcache_line_size =
prom_getintdefault(cpu_node, "dcache-line-size", 32);
cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size",
16 * 1024);
cpu_data(id).icache_line_size =
prom_getintdefault(cpu_node, "icache-line-size", 32);
cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size",
4 * 1024 * 1024);
cpu_data(id).ecache_line_size =
prom_getintdefault(cpu_node, "ecache-line-size", 64);
printk("CPU[%d]: Caches "
"D[sz(%d):line_sz(%d)] "
"I[sz(%d):line_sz(%d)] "
"E[sz(%d):line_sz(%d)]\n",
id,
cpu_data(id).dcache_size, cpu_data(id).dcache_line_size,
cpu_data(id).icache_size, cpu_data(id).icache_line_size,
cpu_data(id).ecache_size, cpu_data(id).ecache_line_size);
}
static void smp_setup_percpu_timer(void);

View file

@ -119,8 +119,8 @@ startup_continue:
sethi %hi(itlb_load), %g2
or %g2, %lo(itlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
sethi %hi(mmu_ihandle_cache), %g2
lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@ -156,8 +156,8 @@ startup_continue:
sethi %hi(itlb_load), %g2
or %g2, %lo(itlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
sethi %hi(mmu_ihandle_cache), %g2
lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE + 0x400000), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@ -190,8 +190,8 @@ do_dtlb:
sethi %hi(dtlb_load), %g2
or %g2, %lo(dtlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
sethi %hi(mmu_ihandle_cache), %g2
lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]
@ -228,8 +228,8 @@ do_dtlb:
sethi %hi(dtlb_load), %g2
or %g2, %lo(dtlb_load), %g2
stx %g2, [%sp + 2047 + 128 + 0x18]
sethi %hi(mmu_ihandle_cache), %g2
lduw [%g2 + %lo(mmu_ihandle_cache)], %g2
sethi %hi(prom_mmu_ihandle_cache), %g2
lduw [%g2 + %lo(prom_mmu_ihandle_cache)], %g2
stx %g2, [%sp + 2047 + 128 + 0x20]
sethi %hi(KERNBASE + 0x400000), %g2
stx %g2, [%sp + 2047 + 128 + 0x28]

View file

@ -869,14 +869,19 @@ static void cheetah_flush_ecache_line(unsigned long physaddr)
*/
static void __cheetah_flush_icache(void)
{
unsigned long i;
unsigned int icache_size, icache_line_size;
unsigned long addr;
icache_size = local_cpu_data().icache_size;
icache_line_size = local_cpu_data().icache_line_size;
/* Clear the valid bits in all the tags. */
for (i = 0; i < (1 << 15); i += (1 << 5)) {
for (addr = 0; addr < icache_size; addr += icache_line_size) {
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (i | (2 << 3)), "i" (ASI_IC_TAG));
: "r" (addr | (2 << 3)),
"i" (ASI_IC_TAG));
}
}
@ -904,13 +909,17 @@ static void cheetah_flush_icache(void)
static void cheetah_flush_dcache(void)
{
unsigned long i;
unsigned int dcache_size, dcache_line_size;
unsigned long addr;
for (i = 0; i < (1 << 16); i += (1 << 5)) {
dcache_size = local_cpu_data().dcache_size;
dcache_line_size = local_cpu_data().dcache_line_size;
for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (i), "i" (ASI_DCACHE_TAG));
: "r" (addr), "i" (ASI_DCACHE_TAG));
}
}
@ -921,24 +930,29 @@ static void cheetah_flush_dcache(void)
*/
static void cheetah_plus_zap_dcache_parity(void)
{
unsigned long i;
unsigned int dcache_size, dcache_line_size;
unsigned long addr;
for (i = 0; i < (1 << 16); i += (1 << 5)) {
unsigned long tag = (i >> 14);
unsigned long j;
dcache_size = local_cpu_data().dcache_size;
dcache_line_size = local_cpu_data().dcache_line_size;
for (addr = 0; addr < dcache_size; addr += dcache_line_size) {
unsigned long tag = (addr >> 14);
unsigned long line;
__asm__ __volatile__("membar #Sync\n\t"
"stxa %0, [%1] %2\n\t"
"membar #Sync"
: /* no outputs */
: "r" (tag), "r" (i),
: "r" (tag), "r" (addr),
"i" (ASI_DCACHE_UTAG));
for (j = i; j < i + (1 << 5); j += (1 << 3))
for (line = addr; line < addr + dcache_line_size; line += 8)
__asm__ __volatile__("membar #Sync\n\t"
"stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
: "r" (j), "i" (ASI_DCACHE_DATA));
: "r" (line),
"i" (ASI_DCACHE_DATA));
}
}

View file

@ -9,8 +9,7 @@ ENTRY(_start)
jiffies = jiffies_64;
SECTIONS
{
swapper_pmd_dir = 0x0000000000402000;
empty_pg_dir = 0x0000000000403000;
swapper_low_pmd_dir = 0x0000000000402000;
. = 0x4000;
.text 0x0000000000404000 :
{

View file

@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/kprobes.h>
#include <linux/cache.h>
#include <asm/head.h>
#include <asm/system.h>
@ -42,22 +43,13 @@ extern void device_scan(void);
struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
unsigned long *sparc64_valid_addr_bitmap;
unsigned long *sparc64_valid_addr_bitmap __read_mostly;
/* Ugly, but necessary... -DaveM */
unsigned long phys_base;
unsigned long kern_base;
unsigned long kern_size;
unsigned long pfn_base;
/* This is even uglier. We have a problem where the kernel may not be
* located at phys_base. However, initial __alloc_bootmem() calls need to
* be adjusted to be within the 4-8Megs that the kernel is mapped to, else
* those page mappings wont work. Things are ok after inherit_prom_mappings
* is called though. Dave says he'll clean this up some other time.
* -- BenC
*/
static unsigned long bootmap_base;
unsigned long phys_base __read_mostly;
unsigned long kern_base __read_mostly;
unsigned long kern_size __read_mostly;
unsigned long pfn_base __read_mostly;
/* get_new_mmu_context() uses "cache + 1". */
DEFINE_SPINLOCK(ctx_alloc_lock);
@ -73,7 +65,7 @@ extern unsigned long sparc_ramdisk_image64;
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
struct page *mem_map_zero;
struct page *mem_map_zero __read_mostly;
int bigkernel = 0;
@ -179,8 +171,6 @@ static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long c
: "g1", "g7");
}
extern void __update_mmu_cache(unsigned long mmu_context_hw, unsigned long address, pte_t pte, int code);
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
struct page *page;
@ -207,10 +197,6 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t p
put_cpu();
}
if (get_thread_fault_code())
__update_mmu_cache(CTX_NRBITS(vma->vm_mm->context),
address, pte, get_thread_fault_code());
}
void flush_dcache_page(struct page *page)
@ -309,6 +295,7 @@ struct linux_prom_translation {
unsigned long size;
unsigned long data;
};
static struct linux_prom_translation prom_trans[512] __initdata;
extern unsigned long prom_boot_page;
extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
@ -318,14 +305,63 @@ extern void register_prom_callbacks(void);
/* Exported for SMP bootup purposes. */
unsigned long kern_locked_tte_data;
void __init early_pgtable_allocfail(char *type)
/* Exported for kernel TLB miss handling in ktlb.S */
unsigned long prom_pmd_phys __read_mostly;
unsigned int swapper_pgd_zero __read_mostly;
/* Allocate power-of-2 aligned chunks from the end of the
* kernel image. Return physical address.
*/
static inline unsigned long early_alloc_phys(unsigned long size)
{
prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type);
prom_halt();
unsigned long base;
BUILD_BUG_ON(size & (size - 1));
kern_size = (kern_size + (size - 1)) & ~(size - 1);
base = kern_base + kern_size;
kern_size += size;
return base;
}
static inline unsigned long load_phys32(unsigned long pa)
{
unsigned long val;
__asm__ __volatile__("lduwa [%1] %2, %0"
: "=&r" (val)
: "r" (pa), "i" (ASI_PHYS_USE_EC));
return val;
}
static inline unsigned long load_phys64(unsigned long pa)
{
unsigned long val;
__asm__ __volatile__("ldxa [%1] %2, %0"
: "=&r" (val)
: "r" (pa), "i" (ASI_PHYS_USE_EC));
return val;
}
static inline void store_phys32(unsigned long pa, unsigned long val)
{
__asm__ __volatile__("stwa %0, [%1] %2"
: /* no outputs */
: "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
}
static inline void store_phys64(unsigned long pa, unsigned long val)
{
__asm__ __volatile__("stxa %0, [%1] %2"
: /* no outputs */
: "r" (val), "r" (pa), "i" (ASI_PHYS_USE_EC));
}
#define BASE_PAGE_SIZE 8192
static pmd_t *prompmd;
/*
* Translate PROM's mapping we capture at boot time into physical address.
@ -333,278 +369,172 @@ static pmd_t *prompmd;
*/
unsigned long prom_virt_to_phys(unsigned long promva, int *error)
{
pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff);
pte_t *ptep;
unsigned long pmd_phys = (prom_pmd_phys +
((promva >> 23) & 0x7ff) * sizeof(pmd_t));
unsigned long pte_phys;
pmd_t pmd_ent;
pte_t pte_ent;
unsigned long base;
if (pmd_none(*pmdp)) {
pmd_val(pmd_ent) = load_phys32(pmd_phys);
if (pmd_none(pmd_ent)) {
if (error)
*error = 1;
return(0);
return 0;
}
ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
if (!pte_present(*ptep)) {
pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL;
pte_phys += ((promva >> 13) & 0x3ff) * sizeof(pte_t);
pte_val(pte_ent) = load_phys64(pte_phys);
if (!pte_present(pte_ent)) {
if (error)
*error = 1;
return(0);
return 0;
}
if (error) {
*error = 0;
return(pte_val(*ptep));
return pte_val(pte_ent);
}
base = pte_val(*ptep) & _PAGE_PADDR;
return(base + (promva & (BASE_PAGE_SIZE - 1)));
base = pte_val(pte_ent) & _PAGE_PADDR;
return (base + (promva & (BASE_PAGE_SIZE - 1)));
}
static void inherit_prom_mappings(void)
/* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
* HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte
* scheme (also, see rant in inherit_locked_prom_mappings()).
*/
static void __init build_obp_range(unsigned long start, unsigned long end, unsigned long data)
{
struct linux_prom_translation *trans;
unsigned long phys_page, tte_vaddr, tte_data;
void (*remap_func)(unsigned long, unsigned long, int);
pmd_t *pmdp;
pte_t *ptep;
int node, n, i, tsz;
extern unsigned int obp_iaddr_patch[2], obp_daddr_patch[2];
unsigned long vaddr;
for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) {
unsigned long val, pte_phys, pmd_phys;
pmd_t pmd_ent;
int i;
pmd_phys = (prom_pmd_phys +
(((vaddr >> 23) & 0x7ff) * sizeof(pmd_t)));
pmd_val(pmd_ent) = load_phys32(pmd_phys);
if (pmd_none(pmd_ent)) {
pte_phys = early_alloc_phys(BASE_PAGE_SIZE);
for (i = 0; i < BASE_PAGE_SIZE / sizeof(pte_t); i++)
store_phys64(pte_phys+i*sizeof(pte_t),0);
pmd_val(pmd_ent) = pte_phys >> 11UL;
store_phys32(pmd_phys, pmd_val(pmd_ent));
}
pte_phys = (unsigned long)pmd_val(pmd_ent) << 11UL;
pte_phys += (((vaddr >> 13) & 0x3ff) * sizeof(pte_t));
val = data;
/* Clear diag TTE bits. */
if (tlb_type == spitfire)
val &= ~0x0003fe0000000000UL;
store_phys64(pte_phys, val | _PAGE_MODIFIED);
data += BASE_PAGE_SIZE;
}
}
static inline int in_obp_range(unsigned long vaddr)
{
return (vaddr >= LOW_OBP_ADDRESS &&
vaddr < HI_OBP_ADDRESS);
}
#define OBP_PMD_SIZE 2048
static void __init build_obp_pgtable(int prom_trans_ents)
{
unsigned long i;
prom_pmd_phys = early_alloc_phys(OBP_PMD_SIZE);
for (i = 0; i < OBP_PMD_SIZE; i += 4)
store_phys32(prom_pmd_phys + i, 0);
for (i = 0; i < prom_trans_ents; i++) {
unsigned long start, end;
if (!in_obp_range(prom_trans[i].virt))
continue;
start = prom_trans[i].virt;
end = start + prom_trans[i].size;
if (end > HI_OBP_ADDRESS)
end = HI_OBP_ADDRESS;
build_obp_range(start, end, prom_trans[i].data);
}
}
/* Read OBP translations property into 'prom_trans[]'.
* Return the number of entries.
*/
static int __init read_obp_translations(void)
{
int n, node;
node = prom_finddevice("/virtual-memory");
n = prom_getproplen(node, "translations");
if (n == 0 || n == -1) {
prom_printf("Couldn't get translation property\n");
if (unlikely(n == 0 || n == -1)) {
prom_printf("prom_mappings: Couldn't get size.\n");
prom_halt();
}
n += 5 * sizeof(struct linux_prom_translation);
for (tsz = 1; tsz < n; tsz <<= 1)
/* empty */;
trans = __alloc_bootmem(tsz, SMP_CACHE_BYTES, bootmap_base);
if (trans == NULL) {
prom_printf("inherit_prom_mappings: Cannot alloc translations.\n");
if (unlikely(n > sizeof(prom_trans))) {
prom_printf("prom_mappings: Size %Zd is too big.\n", n);
prom_halt();
}
memset(trans, 0, tsz);
if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
prom_printf("Couldn't get translation property\n");
if ((n = prom_getproperty(node, "translations",
(char *)&prom_trans[0],
sizeof(prom_trans))) == -1) {
prom_printf("prom_mappings: Couldn't get property.\n");
prom_halt();
}
n = n / sizeof(*trans);
n = n / sizeof(struct linux_prom_translation);
return n;
}
/*
* The obp translations are saved based on 8k pagesize, since obp can
* use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000,
* ie obp range, are handled in entry.S and do not use the vpte scheme
* (see rant in inherit_locked_prom_mappings()).
*/
#define OBP_PMD_SIZE 2048
prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base);
if (prompmd == NULL)
early_pgtable_allocfail("pmd");
memset(prompmd, 0, OBP_PMD_SIZE);
for (i = 0; i < n; i++) {
unsigned long vaddr;
if (trans[i].virt >= LOW_OBP_ADDRESS && trans[i].virt < HI_OBP_ADDRESS) {
for (vaddr = trans[i].virt;
((vaddr < trans[i].virt + trans[i].size) &&
(vaddr < HI_OBP_ADDRESS));
vaddr += BASE_PAGE_SIZE) {
unsigned long val;
pmdp = prompmd + ((vaddr >> 23) & 0x7ff);
if (pmd_none(*pmdp)) {
ptep = __alloc_bootmem(BASE_PAGE_SIZE,
BASE_PAGE_SIZE,
bootmap_base);
if (ptep == NULL)
early_pgtable_allocfail("pte");
memset(ptep, 0, BASE_PAGE_SIZE);
pmd_set(pmdp, ptep);
}
ptep = (pte_t *)__pmd_page(*pmdp) +
((vaddr >> 13) & 0x3ff);
val = trans[i].data;
/* Clear diag TTE bits. */
if (tlb_type == spitfire)
val &= ~0x0003fe0000000000UL;
set_pte_at(&init_mm, vaddr,
ptep, __pte(val | _PAGE_MODIFIED));
trans[i].data += BASE_PAGE_SIZE;
}
}
}
phys_page = __pa(prompmd);
obp_iaddr_patch[0] |= (phys_page >> 10);
obp_iaddr_patch[1] |= (phys_page & 0x3ff);
flushi((long)&obp_iaddr_patch[0]);
obp_daddr_patch[0] |= (phys_page >> 10);
obp_daddr_patch[1] |= (phys_page & 0x3ff);
flushi((long)&obp_daddr_patch[0]);
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf("Remapping the kernel... ");
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"flush %%g6"
: /* No outputs */
: "r" (0), "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
switch (tlb_type) {
default:
case spitfire:
phys_page = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
break;
case cheetah:
case cheetah_plus:
phys_page = cheetah_get_litlb_data(sparc64_highest_locked_tlbent());
break;
};
phys_page &= _PAGE_PADDR;
phys_page += ((unsigned long)&prom_boot_page -
(unsigned long)KERNBASE);
if (tlb_type == spitfire) {
/* Lock this into i/d tlb entry 59 */
__asm__ __volatile__(
"stxa %%g0, [%2] %3\n\t"
"stxa %0, [%1] %4\n\t"
"membar #Sync\n\t"
"flush %%g6\n\t"
"stxa %%g0, [%2] %5\n\t"
"stxa %0, [%1] %6\n\t"
"membar #Sync\n\t"
"flush %%g6"
: : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
_PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
"r" (59 << 3), "r" (TLB_TAG_ACCESS),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
"i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
: "memory");
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
/* Lock this into i/d tlb-0 entry 11 */
__asm__ __volatile__(
"stxa %%g0, [%2] %3\n\t"
"stxa %0, [%1] %4\n\t"
"membar #Sync\n\t"
"flush %%g6\n\t"
"stxa %%g0, [%2] %5\n\t"
"stxa %0, [%1] %6\n\t"
"membar #Sync\n\t"
"flush %%g6"
: : "r" (phys_page | _PAGE_VALID | _PAGE_SZ8K | _PAGE_CP |
_PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W),
"r" ((0 << 16) | (11 << 3)), "r" (TLB_TAG_ACCESS),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS),
"i" (ASI_IMMU), "i" (ASI_ITLB_DATA_ACCESS)
: "memory");
} else {
/* Implement me :-) */
BUG();
}
static void __init remap_kernel(void)
{
unsigned long phys_page, tte_vaddr, tte_data;
int tlb_ent = sparc64_highest_locked_tlbent();
tte_vaddr = (unsigned long) KERNBASE;
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"flush %%g6"
: /* No outputs */
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
if (tlb_type == spitfire)
tte_data = spitfire_get_dtlb_data(sparc64_highest_locked_tlbent());
else
tte_data = cheetah_get_ldtlb_data(sparc64_highest_locked_tlbent());
phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL;
tte_data = (phys_page | (_PAGE_VALID | _PAGE_SZ4MB |
_PAGE_CP | _PAGE_CV | _PAGE_P |
_PAGE_L | _PAGE_W));
kern_locked_tte_data = tte_data;
remap_func = (void *) ((unsigned long) &prom_remap -
(unsigned long) &prom_boot_page);
/* Spitfire Errata #32 workaround */
/* NOTE: Using plain zero for the context value is
* correct here, we are not using the Linux trap
* tables yet so we should not use the special
* UltraSPARC-III+ page size encodings yet.
*/
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
"flush %%g6"
: /* No outputs */
: "r" (0),
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
remap_func((tlb_type == spitfire ?
(spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
(cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
(unsigned long) KERNBASE,
prom_get_mmu_ihandle());
if (bigkernel)
remap_func(((tte_data + 0x400000) & _PAGE_PADDR),
(unsigned long) KERNBASE + 0x400000, prom_get_mmu_ihandle());
/* Flush out that temporary mapping. */
spitfire_flush_dtlb_nucleus_page(0x0);
spitfire_flush_itlb_nucleus_page(0x0);
/* Now lock us back into the TLBs via OBP. */
prom_dtlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
prom_itlb_load(sparc64_highest_locked_tlbent(), tte_data, tte_vaddr);
/* Now lock us into the TLBs via OBP. */
prom_dtlb_load(tlb_ent, tte_data, tte_vaddr);
prom_itlb_load(tlb_ent, tte_data, tte_vaddr);
if (bigkernel) {
prom_dtlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000,
tte_vaddr + 0x400000);
prom_itlb_load(sparc64_highest_locked_tlbent()-1, tte_data + 0x400000,
tte_vaddr + 0x400000);
prom_dtlb_load(tlb_ent - 1,
tte_data + 0x400000,
tte_vaddr + 0x400000);
prom_itlb_load(tlb_ent - 1,
tte_data + 0x400000,
tte_vaddr + 0x400000);
}
}
/* Re-read translations property. */
if ((n = prom_getproperty(node, "translations", (char *)trans, tsz)) == -1) {
prom_printf("Couldn't get translation property\n");
prom_halt();
}
n = n / sizeof(*trans);
static void __init inherit_prom_mappings(void)
{
int n;
for (i = 0; i < n; i++) {
unsigned long vaddr = trans[i].virt;
unsigned long size = trans[i].size;
n = read_obp_translations();
build_obp_pgtable(n);
if (vaddr < 0xf0000000UL) {
unsigned long avoid_start = (unsigned long) KERNBASE;
unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
if (bigkernel)
avoid_end += (4 * 1024 * 1024);
if (vaddr < avoid_start) {
unsigned long top = vaddr + size;
if (top > avoid_start)
top = avoid_start;
prom_unmap(top - vaddr, vaddr);
}
if ((vaddr + size) > avoid_end) {
unsigned long bottom = vaddr;
if (bottom < avoid_end)
bottom = avoid_end;
prom_unmap((vaddr + size) - bottom, bottom);
}
}
}
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf("Remapping the kernel... ");
remap_kernel();
prom_printf("done.\n");
@ -1347,8 +1277,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
#endif
bootmap_size = init_bootmem_node(NODE_DATA(0), bootmap_pfn, pfn_base, end_pfn);
bootmap_base = bootmap_pfn << PAGE_SHIFT;
/* Now register the available physical memory with the
* allocator.
*/
@ -1398,120 +1326,142 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
return end_pfn;
}
#ifdef CONFIG_DEBUG_PAGEALLOC
static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot)
{
unsigned long vstart = PAGE_OFFSET + pstart;
unsigned long vend = PAGE_OFFSET + pend;
unsigned long alloc_bytes = 0UL;
if ((vstart & ~PAGE_MASK) || (vend & ~PAGE_MASK)) {
prom_printf("kernel_map: Unaligned sp_banks[%lx:%lx]\n",
vstart, vend);
prom_halt();
}
while (vstart < vend) {
unsigned long this_end, paddr = __pa(vstart);
pgd_t *pgd = pgd_offset_k(vstart);
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pud = pud_offset(pgd, vstart);
if (pud_none(*pud)) {
pmd_t *new;
new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
alloc_bytes += PAGE_SIZE;
pud_populate(&init_mm, pud, new);
}
pmd = pmd_offset(pud, vstart);
if (!pmd_present(*pmd)) {
pte_t *new;
new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
alloc_bytes += PAGE_SIZE;
pmd_populate_kernel(&init_mm, pmd, new);
}
pte = pte_offset_kernel(pmd, vstart);
this_end = (vstart + PMD_SIZE) & PMD_MASK;
if (this_end > vend)
this_end = vend;
while (vstart < this_end) {
pte_val(*pte) = (paddr | pgprot_val(prot));
vstart += PAGE_SIZE;
paddr += PAGE_SIZE;
pte++;
}
}
return alloc_bytes;
}
extern struct linux_mlist_p1275 *prom_ptot_ptr;
extern unsigned int kvmap_linear_patch[1];
static void __init kernel_physical_mapping_init(void)
{
struct linux_mlist_p1275 *p = prom_ptot_ptr;
unsigned long mem_alloced = 0UL;
while (p) {
unsigned long phys_start, phys_end;
phys_start = p->start_adr;
phys_end = phys_start + p->num_bytes;
mem_alloced += kernel_map_range(phys_start, phys_end,
PAGE_KERNEL);
p = p->theres_more;
}
printk("Allocated %ld bytes for kernel page tables.\n",
mem_alloced);
kvmap_linear_patch[0] = 0x01000000; /* nop */
flushi(&kvmap_linear_patch[0]);
__flush_tlb_all();
}
void kernel_map_pages(struct page *page, int numpages, int enable)
{
unsigned long phys_start = page_to_pfn(page) << PAGE_SHIFT;
unsigned long phys_end = phys_start + (numpages * PAGE_SIZE);
kernel_map_range(phys_start, phys_end,
(enable ? PAGE_KERNEL : __pgprot(0)));
/* we should perform an IPI and flush all tlbs,
* but that can deadlock->flush only current cpu.
*/
__flush_tlb_kernel_range(PAGE_OFFSET + phys_start,
PAGE_OFFSET + phys_end);
}
#endif
/* paging_init() sets up the page tables */
extern void cheetah_ecache_flush_init(void);
static unsigned long last_valid_pfn;
pgd_t swapper_pg_dir[2048];
void __init paging_init(void)
{
extern pmd_t swapper_pmd_dir[1024];
extern unsigned int sparc64_vpte_patchme1[1];
extern unsigned int sparc64_vpte_patchme2[1];
unsigned long alias_base = kern_base + PAGE_OFFSET;
unsigned long second_alias_page = 0;
unsigned long pt, flags, end_pfn, pages_avail;
unsigned long shift = alias_base - ((unsigned long)KERNBASE);
unsigned long end_pfn, pages_avail, shift;
unsigned long real_end;
set_bit(0, mmu_context_bmap);
shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE);
real_end = (unsigned long)_end;
if ((real_end > ((unsigned long)KERNBASE + 0x400000)))
bigkernel = 1;
#ifdef CONFIG_BLK_DEV_INITRD
if (sparc_ramdisk_image || sparc_ramdisk_image64)
real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size));
#endif
/* We assume physical memory starts at some 4mb multiple,
* if this were not true we wouldn't boot up to this point
* anyways.
*/
pt = kern_base | _PAGE_VALID | _PAGE_SZ4MB;
pt |= _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W;
local_irq_save(flags);
if (tlb_type == spitfire) {
__asm__ __volatile__(
" stxa %1, [%0] %3\n"
" stxa %2, [%5] %4\n"
" membar #Sync\n"
" flush %%g6\n"
" nop\n"
" nop\n"
" nop\n"
: /* No outputs */
: "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
: "memory");
if (real_end >= KERNBASE + 0x340000) {
second_alias_page = alias_base + 0x400000;
__asm__ __volatile__(
" stxa %1, [%0] %3\n"
" stxa %2, [%5] %4\n"
" membar #Sync\n"
" flush %%g6\n"
" nop\n"
" nop\n"
" nop\n"
: /* No outputs */
: "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (60 << 3)
: "memory");
}
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
__asm__ __volatile__(
" stxa %1, [%0] %3\n"
" stxa %2, [%5] %4\n"
" membar #Sync\n"
" flush %%g6\n"
" nop\n"
" nop\n"
" nop\n"
: /* No outputs */
: "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3))
: "memory");
if (real_end >= KERNBASE + 0x340000) {
second_alias_page = alias_base + 0x400000;
__asm__ __volatile__(
" stxa %1, [%0] %3\n"
" stxa %2, [%5] %4\n"
" membar #Sync\n"
" flush %%g6\n"
" nop\n"
" nop\n"
" nop\n"
: /* No outputs */
: "r" (TLB_TAG_ACCESS), "r" (second_alias_page), "r" (pt + 0x400000),
"i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (12<<3))
: "memory");
}
if ((real_end > ((unsigned long)KERNBASE + 0x800000))) {
prom_printf("paging_init: Kernel > 8MB, too large.\n");
prom_halt();
}
local_irq_restore(flags);
/* Now set kernel pgd to upper alias so physical page computations
/* Set kernel pgd to upper alias so physical page computations
* work.
*/
init_mm.pgd += ((shift) / (sizeof(pgd_t)));
memset(swapper_pmd_dir, 0, sizeof(swapper_pmd_dir));
memset(swapper_low_pmd_dir, 0, sizeof(swapper_low_pmd_dir));
/* Now can init the kernel/bad page tables. */
pud_set(pud_offset(&swapper_pg_dir[0], 0),
swapper_pmd_dir + (shift / sizeof(pgd_t)));
swapper_low_pmd_dir + (shift / sizeof(pgd_t)));
sparc64_vpte_patchme1[0] |=
(((unsigned long)pgd_val(init_mm.pgd[0])) >> 10);
sparc64_vpte_patchme2[0] |=
(((unsigned long)pgd_val(init_mm.pgd[0])) & 0x3ff);
flushi((long)&sparc64_vpte_patchme1[0]);
swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
/* Setup bootmem... */
pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
/* Inherit non-locked OBP mappings. */
inherit_prom_mappings();
@ -1527,13 +1477,16 @@ void __init paging_init(void)
inherit_locked_prom_mappings(1);
/* We only created DTLB mapping of this stuff. */
spitfire_flush_dtlb_nucleus_page(alias_base);
if (second_alias_page)
spitfire_flush_dtlb_nucleus_page(second_alias_page);
__flush_tlb_all();
/* Setup bootmem... */
pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
#ifdef CONFIG_DEBUG_PAGEALLOC
kernel_physical_mapping_init();
#endif
{
unsigned long zones_size[MAX_NR_ZONES];
unsigned long zholes_size[MAX_NR_ZONES];
@ -1695,8 +1648,7 @@ void __init mem_init(void)
i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
i += 1;
sparc64_valid_addr_bitmap = (unsigned long *)
__alloc_bootmem(i << 3, SMP_CACHE_BYTES, bootmap_base);
sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3);
if (sparc64_valid_addr_bitmap == NULL) {
prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
prom_halt();
@ -1749,7 +1701,7 @@ void __init mem_init(void)
cheetah_ecache_flush_init();
}
void free_initmem (void)
void free_initmem(void)
{
unsigned long addr, initend;

View file

@ -144,42 +144,29 @@ __flush_icache_page: /* %o0 = phys_page */
#define DTAG_MASK 0x3
/* This routine is Spitfire specific so the hardcoded
* D-cache size and line-size are OK.
*/
.align 64
.globl __flush_dcache_page
__flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
sethi %uhi(PAGE_OFFSET), %g1
sllx %g1, 32, %g1
sub %o0, %g1, %o0
clr %o4
srlx %o0, 11, %o0
sethi %hi(1 << 14), %o2
1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group
add %o4, (1 << 5), %o4 ! IEU0
ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group
add %o4, (1 << 5), %o4 ! IEU0
ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available
add %o4, (1 << 5), %o4 ! IEU0
andn %o3, DTAG_MASK, %o3 ! IEU1
ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group
add %o4, (1 << 5), %o4 ! IEU0
andn %g1, DTAG_MASK, %g1 ! IEU1
cmp %o0, %o3 ! IEU1 Group
be,a,pn %xcc, dflush1 ! CTI
sub %o4, (4 << 5), %o4 ! IEU0 (Group)
cmp %o0, %g1 ! IEU1 Group
andn %g2, DTAG_MASK, %g2 ! IEU0
be,a,pn %xcc, dflush2 ! CTI
sub %o4, (3 << 5), %o4 ! IEU0 (Group)
cmp %o0, %g2 ! IEU1 Group
andn %g3, DTAG_MASK, %g3 ! IEU0
be,a,pn %xcc, dflush3 ! CTI
sub %o4, (2 << 5), %o4 ! IEU0 (Group)
cmp %o0, %g3 ! IEU1 Group
be,a,pn %xcc, dflush4 ! CTI
sub %o4, (1 << 5), %o4 ! IEU0
2: cmp %o4, %o2 ! IEU1 Group
bne,pt %xcc, 1b ! CTI
nop ! IEU0
sub %o0, %g1, %o0 ! physical address
srlx %o0, 11, %o0 ! make D-cache TAG
sethi %hi(1 << 14), %o2 ! D-cache size
sub %o2, (1 << 5), %o2 ! D-cache line size
1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG
andcc %o3, DTAG_MASK, %g0 ! Valid?
be,pn %xcc, 2f ! Nope, branch
andn %o3, DTAG_MASK, %o3 ! Clear valid bits
cmp %o3, %o0 ! TAG match?
bne,pt %xcc, 2f ! Nope, branch
nop
stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG
membar #Sync
2: brnz,pt %o2, 1b
sub %o2, (1 << 5), %o2 ! D-cache line size
/* The I-cache does not snoop local stores so we
* better flush that too when necessary.
@ -189,48 +176,9 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
retl
nop
dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG
add %o4, (1 << 5), %o4
dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG
add %o4, (1 << 5), %o4
dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG
add %o4, (1 << 5), %o4
dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG
add %o4, (1 << 5), %o4
membar #Sync
ba,pt %xcc, 2b
nop
#endif /* DCACHE_ALIASING_POSSIBLE */
.previous .text
.align 32
__prefill_dtlb:
rdpr %pstate, %g7
wrpr %g7, PSTATE_IE, %pstate
mov TLB_TAG_ACCESS, %g1
stxa %o5, [%g1] ASI_DMMU
stxa %o2, [%g0] ASI_DTLB_DATA_IN
flush %g6
retl
wrpr %g7, %pstate
__prefill_itlb:
rdpr %pstate, %g7
wrpr %g7, PSTATE_IE, %pstate
mov TLB_TAG_ACCESS, %g1
stxa %o5, [%g1] ASI_IMMU
stxa %o2, [%g0] ASI_ITLB_DATA_IN
flush %g6
retl
wrpr %g7, %pstate
.globl __update_mmu_cache
__update_mmu_cache: /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */
srlx %o1, PAGE_SHIFT, %o1
andcc %o3, FAULT_CODE_DTLB, %g0
sllx %o1, PAGE_SHIFT, %o5
bne,pt %xcc, __prefill_dtlb
or %o5, %o0, %o5
ba,a,pt %xcc, __prefill_itlb
.previous
/* Cheetah specific versions, patched at boot time. */
__cheetah_flush_tlb_mm: /* 18 insns */
@ -283,7 +231,7 @@ __cheetah_flush_tlb_pending: /* 26 insns */
wrpr %g7, 0x0, %pstate
#ifdef DCACHE_ALIASING_POSSIBLE
flush_dcpage_cheetah: /* 11 insns */
__cheetah_flush_dcache_page: /* 11 insns */
sethi %uhi(PAGE_OFFSET), %g1
sllx %g1, 32, %g1
sub %o0, %g1, %o0
@ -329,8 +277,8 @@ cheetah_patch_cachetlbops:
#ifdef DCACHE_ALIASING_POSSIBLE
sethi %hi(__flush_dcache_page), %o0
or %o0, %lo(__flush_dcache_page), %o0
sethi %hi(flush_dcpage_cheetah), %o1
or %o1, %lo(flush_dcpage_cheetah), %o1
sethi %hi(__cheetah_flush_dcache_page), %o1
or %o1, %lo(__cheetah_flush_dcache_page), %o1
call cheetah_patch_one
mov 11, %o2
#endif /* DCACHE_ALIASING_POSSIBLE */

View file

@ -7,4 +7,4 @@ EXTRA_AFLAGS := -ansi
EXTRA_CFLAGS := -Werror
lib-y := bootstr.o devops.o init.o memory.o misc.o \
tree.o console.o printf.o p1275.o map.o cif.o
tree.o console.o printf.o p1275.o cif.o

View file

@ -67,7 +67,7 @@ prom_putchar(char c)
}
void
prom_puts(char *s, int len)
prom_puts(const char *s, int len)
{
p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
P1275_INOUT(3,1),

View file

@ -16,7 +16,7 @@
* Returns 0 on failure.
*/
int
prom_devopen(char *dstr)
prom_devopen(const char *dstr)
{
return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1,1),

View file

@ -46,7 +46,7 @@ void __init prom_init(void *cif_handler, void *cif_stack)
if((prom_root_node == 0) || (prom_root_node == -1))
prom_halt();
prom_chosen_node = prom_finddevice("/chosen");
prom_chosen_node = prom_finddevice(prom_chosen_path);
if (!prom_chosen_node || prom_chosen_node == -1)
prom_halt();

View file

@ -1,72 +0,0 @@
/* $Id: map.S,v 1.2 1999/11/19 05:53:02 davem Exp $
* map.S: Tricky coding required to fixup the kernel OBP maps
* properly.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
.text
.align 8192
.globl prom_boot_page
prom_boot_page:
call_method:
.asciz "call-method"
.align 8
map:
.asciz "map"
.align 8
/* When we are invoked, our caller has remapped us to
* page zero, therefore we must use PC relative addressing
* for everything after we begin performing the unmap/map
* calls.
*/
.globl prom_remap
prom_remap: /* %o0 = physpage, %o1 = virtpage, %o2 = mmu_ihandle */
rd %pc, %g1
srl %o2, 0, %o2 ! kill sign extension
sethi %hi(p1275buf), %g2
or %g2, %lo(p1275buf), %g2
ldx [%g2 + 0x10], %g3 ! prom_cif_stack
save %g3, -(192 + 128), %sp
ldx [%g2 + 0x08], %l0 ! prom_cif_handler
mov %g6, %i3
mov %g4, %i4
mov %g5, %i5
flushw
sethi %hi(prom_remap - call_method), %g7
or %g7, %lo(prom_remap - call_method), %g7
sub %g1, %g7, %l2 ! call-method string
sethi %hi(prom_remap - map), %g7
or %g7, %lo(prom_remap - map), %g7
sub %g1, %g7, %l4 ! map string
/* OK, map the 4MB region we really live at. */
stx %l2, [%sp + 2047 + 128 + 0x00] ! call-method
mov 7, %l5
stx %l5, [%sp + 2047 + 128 + 0x08] ! num_args
mov 1, %l5
stx %l5, [%sp + 2047 + 128 + 0x10] ! num_rets
stx %l4, [%sp + 2047 + 128 + 0x18] ! map
stx %i2, [%sp + 2047 + 128 + 0x20] ! mmu_ihandle
mov -1, %l5
stx %l5, [%sp + 2047 + 128 + 0x28] ! mode == default
sethi %hi(4 * 1024 * 1024), %l5
stx %l5, [%sp + 2047 + 128 + 0x30] ! size
stx %i1, [%sp + 2047 + 128 + 0x38] ! vaddr
stx %g0, [%sp + 2047 + 128 + 0x40] ! filler
stx %i0, [%sp + 2047 + 128 + 0x48] ! paddr
call %l0
add %sp, (2047 + 128), %o0 ! argument array
/* Restore hard-coded globals. */
mov %i3, %g6
mov %i4, %g4
mov %i5, %g5
/* Wheee.... we are done. */
ret
restore
.align 8192

View file

@ -17,14 +17,14 @@
#include <asm/system.h>
/* Reset and reboot the machine with the command 'bcommand'. */
void prom_reboot(char *bcommand)
void prom_reboot(const char *bcommand)
{
p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 0), bcommand);
}
/* Forth evaluate the expression contained in 'fstring'. */
void prom_feval(char *fstring)
void prom_feval(const char *fstring)
{
if (!fstring || fstring[0] == 0)
return;
@ -148,21 +148,19 @@ void prom_set_trap_table(unsigned long tba)
p1275_cmd("SUNW,set-trap-table", P1275_INOUT(1, 0), tba);
}
int mmu_ihandle_cache = 0;
int prom_get_mmu_ihandle(void)
{
int node, ret;
if (mmu_ihandle_cache != 0)
return mmu_ihandle_cache;
if (prom_mmu_ihandle_cache != 0)
return prom_mmu_ihandle_cache;
node = prom_finddevice("/chosen");
ret = prom_getint(node, "mmu");
node = prom_finddevice(prom_chosen_path);
ret = prom_getint(node, prom_mmu_name);
if (ret == -1 || ret == 0)
mmu_ihandle_cache = -1;
prom_mmu_ihandle_cache = -1;
else
mmu_ihandle_cache = ret;
prom_mmu_ihandle_cache = ret;
return ret;
}
@ -190,7 +188,7 @@ long prom_itlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
return p1275_cmd("call-method",
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
@ -207,7 +205,7 @@ long prom_dtlb_load(unsigned long index,
unsigned long tte_data,
unsigned long vaddr)
{
return p1275_cmd("call-method",
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
@ -223,13 +221,13 @@ long prom_dtlb_load(unsigned long index,
int prom_map(int mode, unsigned long size,
unsigned long vaddr, unsigned long paddr)
{
int ret = p1275_cmd("call-method",
int ret = p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_ARG(4, P1275_ARG_IN_64B) |
P1275_ARG(6, P1275_ARG_IN_64B) |
P1275_INOUT(7, 1)),
"map",
prom_map_name,
prom_get_mmu_ihandle(),
mode,
size,
@ -244,12 +242,12 @@ int prom_map(int mode, unsigned long size,
void prom_unmap(unsigned long size, unsigned long vaddr)
{
p1275_cmd("call-method",
p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(2, P1275_ARG_IN_64B) |
P1275_ARG(3, P1275_ARG_IN_64B) |
P1275_INOUT(4, 0)),
"unmap",
prom_unmap_name,
prom_get_mmu_ihandle(),
size,
vaddr);
@ -258,7 +256,7 @@ void prom_unmap(unsigned long size, unsigned long vaddr)
/* Set aside physical memory which is not touched or modified
* across soft resets.
*/
unsigned long prom_retain(char *name,
unsigned long prom_retain(const char *name,
unsigned long pa_low, unsigned long pa_high,
long size, long align)
{
@ -290,7 +288,7 @@ int prom_getunumber(int syndrome_code,
unsigned long phys_addr,
char *buf, int buflen)
{
return p1275_cmd("call-method",
return p1275_cmd(prom_callmethod_name,
(P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_ARG(3, P1275_ARG_OUT_BUF) |
P1275_ARG(6, P1275_ARG_IN_64B) |

View file

@ -46,7 +46,7 @@ static inline unsigned long spitfire_get_primary_context(void)
*/
DEFINE_SPINLOCK(prom_entry_lock);
long p1275_cmd (char *service, long fmt, ...)
long p1275_cmd(const char *service, long fmt, ...)
{
char *p, *q;
unsigned long flags;

View file

@ -34,7 +34,7 @@ prom_write(const char *buf, unsigned int n)
}
void
prom_printf(char *fmt, ...)
prom_printf(const char *fmt, ...)
{
va_list args;
int i;

View file

@ -69,7 +69,7 @@ prom_getsibling(int node)
* Return -1 on error.
*/
__inline__ int
prom_getproplen(int node, char *prop)
prom_getproplen(int node, const char *prop)
{
if((!node) || (!prop)) return -1;
return p1275_cmd ("getproplen",
@ -83,20 +83,20 @@ prom_getproplen(int node, char *prop)
* was successful the length will be returned, else -1 is returned.
*/
__inline__ int
prom_getproperty(int node, char *prop, char *buffer, int bufsize)
prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
{
int plen;
plen = prom_getproplen(node, prop);
if((plen > bufsize) || (plen == 0) || (plen == -1))
if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
return -1;
else {
} else {
/* Ok, things seem all right. */
return p1275_cmd ("getprop",
P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_ARG(2,P1275_ARG_OUT_BUF)|
P1275_INOUT(4, 1),
node, prop, buffer, P1275_SIZE(plen));
return p1275_cmd(prom_getprop_name,
P1275_ARG(1,P1275_ARG_IN_STRING)|
P1275_ARG(2,P1275_ARG_OUT_BUF)|
P1275_INOUT(4, 1),
node, prop, buffer, P1275_SIZE(plen));
}
}
@ -104,7 +104,7 @@ prom_getproperty(int node, char *prop, char *buffer, int bufsize)
* on failure.
*/
__inline__ int
prom_getint(int node, char *prop)
prom_getint(int node, const char *prop)
{
int intprop;
@ -119,7 +119,7 @@ prom_getint(int node, char *prop)
*/
int
prom_getintdefault(int node, char *property, int deflt)
prom_getintdefault(int node, const char *property, int deflt)
{
int retval;
@ -131,7 +131,7 @@ prom_getintdefault(int node, char *property, int deflt)
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
int
prom_getbool(int node, char *prop)
prom_getbool(int node, const char *prop)
{
int retval;
@ -145,7 +145,7 @@ prom_getbool(int node, char *prop)
* buffer.
*/
void
prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
{
int len;
@ -160,7 +160,7 @@ prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
* YES = 1 NO = 0
*/
int
prom_nodematch(int node, char *name)
prom_nodematch(int node, const char *name)
{
char namebuf[128];
prom_getproperty(node, "name", namebuf, sizeof(namebuf));
@ -172,7 +172,7 @@ prom_nodematch(int node, char *name)
* 'nodename'. Return node if successful, zero if not.
*/
int
prom_searchsiblings(int node_start, char *nodename)
prom_searchsiblings(int node_start, const char *nodename)
{
int thisnode, error;
@ -294,7 +294,7 @@ prom_firstprop(int node, char *buffer)
* property types for this node.
*/
__inline__ char *
prom_nextprop(int node, char *oprop, char *buffer)
prom_nextprop(int node, const char *oprop, char *buffer)
{
char buf[32];
@ -314,15 +314,17 @@ prom_nextprop(int node, char *oprop, char *buffer)
}
int
prom_finddevice(char *name)
prom_finddevice(const char *name)
{
if(!name) return 0;
return p1275_cmd ("finddevice", P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1, 1),
name);
if (!name)
return 0;
return p1275_cmd(prom_finddev_name,
P1275_ARG(0,P1275_ARG_IN_STRING)|
P1275_INOUT(1, 1),
name);
}
int prom_node_has_property(int node, char *prop)
int prom_node_has_property(int node, const char *prop)
{
char buf [32];
@ -339,7 +341,7 @@ int prom_node_has_property(int node, char *prop)
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
int
prom_setprop(int node, char *pname, char *value, int size)
prom_setprop(int node, const char *pname, char *value, int size)
{
if(size == 0) return 0;
if((pname == 0) || (value == 0)) return 0;
@ -364,7 +366,7 @@ prom_inst2pkg(int inst)
* FIXME: Should work for v0 as well
*/
int
prom_pathtoinode(char *path)
prom_pathtoinode(const char *path)
{
int node, inst;

View file

@ -959,9 +959,6 @@ static __init int unsynchronized_tsc(void)
are handled in the OEM check above. */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
return 0;
/* All in a single socket - should be synchronized */
if (cpus_weight(cpu_core_map[0]) == num_online_cpus())
return 0;
#endif
/* Assume multi socket systems are not synchronized */
return num_online_cpus() > 1;

View file

@ -55,7 +55,7 @@ extern void (*pm_power_off)(void);
static int poweroff_powercycle;
/* parameter definition to allow user to flag power cycle */
module_param(poweroff_powercycle, int, 0);
module_param(poweroff_powercycle, int, 0644);
MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
/* Stuff from the get device id command. */

View file

@ -31,16 +31,19 @@
#include <linux/connector.h>
#include <linux/delay.h>
static void cn_queue_wrapper(void *data)
void cn_queue_wrapper(void *data)
{
struct cn_callback_entry *cbq = data;
struct cn_callback_data *d = data;
cbq->cb->callback(cbq->cb->priv);
cbq->destruct_data(cbq->ddata);
cbq->ddata = NULL;
d->callback(d->callback_priv);
d->destruct_data(d->ddata);
d->ddata = NULL;
kfree(d->free);
}
static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callback *cb)
static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *))
{
struct cn_callback_entry *cbq;
@ -50,8 +53,11 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(struct cn_callbac
return NULL;
}
cbq->cb = cb;
INIT_WORK(&cbq->work, &cn_queue_wrapper, cbq);
snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;
INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data);
return cbq;
}
@ -68,12 +74,12 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
return ((i1->idx == i2->idx) && (i1->val == i2->val));
}
int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *))
{
struct cn_callback_entry *cbq, *__cbq;
int found = 0;
cbq = cn_queue_alloc_callback_entry(cb);
cbq = cn_queue_alloc_callback_entry(name, id, callback);
if (!cbq)
return -ENOMEM;
@ -82,7 +88,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
spin_lock_bh(&dev->queue_lock);
list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->cb->id, &cb->id)) {
if (cn_cb_equal(&__cbq->id.id, id)) {
found = 1;
break;
}
@ -99,7 +105,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, struct cn_callback *cb)
cbq->nls = dev->nls;
cbq->seq = 0;
cbq->group = cbq->cb->id.idx;
cbq->group = cbq->id.id.idx;
return 0;
}
@ -111,7 +117,7 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
spin_lock_bh(&dev->queue_lock);
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) {
if (cn_cb_equal(&cbq->cb->id, id)) {
if (cn_cb_equal(&cbq->id.id, id)) {
list_del(&cbq->callback_entry);
found = 1;
break;

View file

@ -84,7 +84,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask)
spin_lock_bh(&dev->cbdev->queue_lock);
list_for_each_entry(__cbq, &dev->cbdev->queue_list,
callback_entry) {
if (cn_cb_equal(&__cbq->cb->id, &msg->id)) {
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
found = 1;
group = __cbq->group;
}
@ -127,42 +127,56 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
{
struct cn_callback_entry *__cbq;
struct cn_dev *dev = &cdev;
int found = 0;
int err = -ENODEV;
spin_lock_bh(&dev->cbdev->queue_lock);
list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->cb->id, &msg->id)) {
/*
* Let's scream if there is some magic and the
* data will arrive asynchronously here.
* [i.e. netlink messages will be queued].
* After the first warning I will fix it
* quickly, but now I think it is
* impossible. --zbr (2004_04_27).
*/
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
if (likely(!test_bit(0, &__cbq->work.pending) &&
__cbq->ddata == NULL)) {
__cbq->cb->priv = msg;
__cbq->data.ddata == NULL)) {
__cbq->data.callback_priv = msg;
__cbq->ddata = data;
__cbq->destruct_data = destruct_data;
__cbq->data.ddata = data;
__cbq->data.destruct_data = destruct_data;
if (queue_work(dev->cbdev->cn_queue,
&__cbq->work))
found = 1;
err = 0;
} else {
printk("%s: cbq->data=%p, "
"work->pending=%08lx.\n",
__func__, __cbq->ddata,
__cbq->work.pending);
WARN_ON(1);
struct work_struct *w;
struct cn_callback_data *d;
w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC);
if (w) {
d = (struct cn_callback_data *)(w+1);
d->callback_priv = msg;
d->callback = __cbq->data.callback;
d->ddata = data;
d->destruct_data = destruct_data;
d->free = w;
INIT_LIST_HEAD(&w->entry);
w->pending = 0;
w->func = &cn_queue_wrapper;
w->data = d;
init_timer(&w->timer);
if (queue_work(dev->cbdev->cn_queue, w))
err = 0;
else {
kfree(w);
err = -EINVAL;
}
} else
err = -ENOMEM;
}
break;
}
}
spin_unlock_bh(&dev->cbdev->queue_lock);
return found ? 0 : -ENODEV;
return err;
}
/*
@ -291,22 +305,10 @@ int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
{
int err;
struct cn_dev *dev = &cdev;
struct cn_callback *cb;
cb = kzalloc(sizeof(*cb), GFP_KERNEL);
if (!cb)
return -ENOMEM;
scnprintf(cb->name, sizeof(cb->name), "%s", name);
memcpy(&cb->id, id, sizeof(cb->id));
cb->callback = callback;
err = cn_queue_add_callback(dev->cbdev, cb);
if (err) {
kfree(cb);
err = cn_queue_add_callback(dev->cbdev, name, id, callback);
if (err)
return err;
}
cn_notify(id, 0);

View file

@ -477,7 +477,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2 ", 0xe37be2b5, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12(" ", "NinjaATA-", 0x3b6e20c8, 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),

View file

@ -69,6 +69,7 @@ struct ib_uverbs_event_file {
struct ib_uverbs_file {
struct kref ref;
struct semaphore mutex;
struct ib_uverbs_device *device;
struct ib_ucontext *ucontext;
struct ib_event_handler event_handler;

View file

@ -76,8 +76,9 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
struct ib_uverbs_get_context_resp resp;
struct ib_udata udata;
struct ib_device *ibdev = file->device->ib_dev;
struct ib_ucontext *ucontext;
int i;
int ret = in_len;
int ret;
if (out_len < sizeof resp)
return -ENOSPC;
@ -85,45 +86,56 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
down(&file->mutex);
if (file->ucontext) {
ret = -EINVAL;
goto err;
}
INIT_UDATA(&udata, buf + sizeof cmd,
(unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp);
file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
if (IS_ERR(file->ucontext)) {
ret = PTR_ERR(file->ucontext);
file->ucontext = NULL;
return ret;
}
ucontext = ibdev->alloc_ucontext(ibdev, &udata);
if (IS_ERR(ucontext))
return PTR_ERR(file->ucontext);
file->ucontext->device = ibdev;
INIT_LIST_HEAD(&file->ucontext->pd_list);
INIT_LIST_HEAD(&file->ucontext->mr_list);
INIT_LIST_HEAD(&file->ucontext->mw_list);
INIT_LIST_HEAD(&file->ucontext->cq_list);
INIT_LIST_HEAD(&file->ucontext->qp_list);
INIT_LIST_HEAD(&file->ucontext->srq_list);
INIT_LIST_HEAD(&file->ucontext->ah_list);
spin_lock_init(&file->ucontext->lock);
ucontext->device = ibdev;
INIT_LIST_HEAD(&ucontext->pd_list);
INIT_LIST_HEAD(&ucontext->mr_list);
INIT_LIST_HEAD(&ucontext->mw_list);
INIT_LIST_HEAD(&ucontext->cq_list);
INIT_LIST_HEAD(&ucontext->qp_list);
INIT_LIST_HEAD(&ucontext->srq_list);
INIT_LIST_HEAD(&ucontext->ah_list);
resp.async_fd = file->async_file.fd;
for (i = 0; i < file->device->num_comp; ++i)
if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
i * sizeof (__u32),
&file->comp_file[i].fd, sizeof (__u32)))
goto err;
&file->comp_file[i].fd, sizeof (__u32))) {
ret = -EFAULT;
goto err_free;
}
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp))
goto err;
&resp, sizeof resp)) {
ret = -EFAULT;
goto err_free;
}
file->ucontext = ucontext;
up(&file->mutex);
return in_len;
err:
ibdev->dealloc_ucontext(file->ucontext);
file->ucontext = NULL;
err_free:
ibdev->dealloc_ucontext(ucontext);
return -EFAULT;
err:
up(&file->mutex);
return ret;
}
ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
@ -352,9 +364,9 @@ retry:
if (ret)
goto err_pd;
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_add_tail(&uobj->list, &file->ucontext->pd_list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
memset(&resp, 0, sizeof resp);
resp.pd_handle = uobj->id;
@ -368,9 +380,9 @@ retry:
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
down(&ib_uverbs_idr_mutex);
idr_remove(&ib_uverbs_pd_idr, uobj->id);
@ -410,9 +422,9 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
kfree(uobj);
@ -512,9 +524,9 @@ retry:
resp.mr_handle = obj->uobject.id;
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@ -527,9 +539,9 @@ retry:
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&obj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
err_unreg:
ib_dereg_mr(mr);
@ -570,9 +582,9 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&memobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
ib_umem_release(file->device->ib_dev, &memobj->umem);
kfree(memobj);
@ -647,9 +659,9 @@ retry:
if (ret)
goto err_cq;
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
memset(&resp, 0, sizeof resp);
resp.cq_handle = uobj->uobject.id;
@ -664,9 +676,9 @@ retry:
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
down(&ib_uverbs_idr_mutex);
idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id);
@ -712,9 +724,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
spin_lock_irq(&file->comp_file[0].lock);
list_for_each_entry_safe(evt, tmp, &uobj->comp_list, obj_list) {
@ -847,9 +859,9 @@ retry:
resp.qp_handle = uobj->uobject.id;
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->qp_list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@ -862,9 +874,9 @@ retry:
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
err_destroy:
ib_destroy_qp(qp);
@ -989,9 +1001,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
spin_lock_irq(&file->async_file.lock);
list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {
@ -1136,9 +1148,9 @@ retry:
resp.srq_handle = uobj->uobject.id;
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
@ -1151,9 +1163,9 @@ retry:
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
err_destroy:
ib_destroy_srq(srq);
@ -1227,9 +1239,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
spin_lock_irq(&file->ucontext->lock);
down(&file->mutex);
list_del(&uobj->uobject.list);
spin_unlock_irq(&file->ucontext->lock);
up(&file->mutex);
spin_lock_irq(&file->async_file.lock);
list_for_each_entry_safe(evt, tmp, &uobj->event_list, obj_list) {

View file

@ -448,7 +448,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
if (hdr.in_words * 4 != count)
return -EINVAL;
if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
if (hdr.command < 0 ||
hdr.command >= ARRAY_SIZE(uverbs_cmd_table) ||
!uverbs_cmd_table[hdr.command])
return -EINVAL;
if (!file->ucontext &&
@ -484,27 +486,29 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
file = kmalloc(sizeof *file +
(dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
GFP_KERNEL);
if (!file)
return -ENOMEM;
if (!file) {
ret = -ENOMEM;
goto err;
}
file->device = dev;
kref_init(&file->ref);
init_MUTEX(&file->mutex);
file->ucontext = NULL;
kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->async_file, file);
if (ret)
goto err;
goto err_kref;
file->async_file.is_async = 1;
kref_get(&file->ref);
for (i = 0; i < dev->num_comp; ++i) {
kref_get(&file->ref);
ret = ib_uverbs_event_init(&file->comp_file[i], file);
if (ret)
goto err_async;
kref_get(&file->ref);
file->comp_file[i].is_async = 0;
}
@ -524,9 +528,16 @@ err_async:
ib_uverbs_event_release(&file->async_file);
err:
err_kref:
/*
* One extra kref_put() because we took a reference before the
* event file creation that failed and got us here.
*/
kref_put(&file->ref, ib_uverbs_release_file);
kref_put(&file->ref, ib_uverbs_release_file);
err:
module_put(dev->ib_dev->owner);
return ret;
}

View file

@ -605,7 +605,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
err = -EINVAL;
goto out;
}
for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) {
if (virt != -1) {
pages[nent * 2] = cpu_to_be64(virt);
virt += 1 << lg;
@ -616,7 +616,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
ts += 1 << (lg - 10);
++tc;
if (nent == MTHCA_MAILBOX_SIZE / 16) {
if (++nent == MTHCA_MAILBOX_SIZE / 16) {
err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
CMD_TIME_CLASS_B, status);
if (err || *status)

View file

@ -836,7 +836,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev)
dev->eq_table.clr_mask =
swab32(1 << (dev->eq_table.inta_pin & 31));
dev->eq_table.clr_int = dev->clr_base +
(dev->eq_table.inta_pin < 31 ? 4 : 0);
(dev->eq_table.inta_pin < 32 ? 4 : 0);
}
dev->eq_table.arm_mask = 0;

View file

@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
int i;
u8 status;
num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE;
num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
if (!table)
@ -529,12 +529,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
goto found;
}
for (i = start; i != end; i += dir)
if (!dev->db_tab->page[i].db_rec) {
page = dev->db_tab->page + i;
goto alloc;
}
if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
ret = -ENOMEM;
goto out;
}
if (group == 0)
++dev->db_tab->max_group1;
else
--dev->db_tab->min_group2;
page = dev->db_tab->page + end;
alloc:
page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
&page->mapping, GFP_KERNEL);
if (!page->db_rec) {
@ -554,10 +567,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
}
bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
if (group == 0)
++dev->db_tab->max_group1;
else
--dev->db_tab->min_group2;
found:
j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);

View file

@ -84,7 +84,7 @@ static int mthca_query_device(struct ib_device *ibdev,
props->vendor_id = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
0xffffff;
props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30));
props->hw_ver = be16_to_cpup((__be16 *) (out_mad->data + 32));
props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32));
memcpy(&props->sys_image_guid, out_mad->data + 4, 8);
memcpy(&props->node_guid, out_mad->data + 12, 8);

View file

@ -230,11 +230,20 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi
static void __hash_remove(struct hash_cell *hc)
{
struct dm_table *table;
/* remove from the dev hash */
list_del(&hc->uuid_list);
list_del(&hc->name_list);
unregister_with_devfs(hc);
dm_set_mdptr(hc->md, NULL);
table = dm_get_table(hc->md);
if (table) {
dm_table_event(table);
dm_table_put(table);
}
dm_put(hc->md);
if (hc->new_map)
dm_table_put(hc->new_map);

View file

@ -329,13 +329,17 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio,
/*
* If we run out of usable paths, should we queue I/O or error it?
*/
static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path)
static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path,
unsigned save_old_value)
{
unsigned long flags;
spin_lock_irqsave(&m->lock, flags);
m->saved_queue_if_no_path = m->queue_if_no_path;
if (save_old_value)
m->saved_queue_if_no_path = m->queue_if_no_path;
else
m->saved_queue_if_no_path = queue_if_no_path;
m->queue_if_no_path = queue_if_no_path;
if (!m->queue_if_no_path && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios);
@ -677,7 +681,7 @@ static int parse_features(struct arg_set *as, struct multipath *m,
return 0;
if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
return queue_if_no_path(m, 1);
return queue_if_no_path(m, 1, 0);
else {
ti->error = "Unrecognised multipath feature request";
return -EINVAL;
@ -1077,7 +1081,7 @@ static void multipath_presuspend(struct dm_target *ti)
{
struct multipath *m = (struct multipath *) ti->private;
queue_if_no_path(m, 0);
queue_if_no_path(m, 0, 1);
}
/*
@ -1222,9 +1226,9 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
if (argc == 1) {
if (!strnicmp(argv[0], MESG_STR("queue_if_no_path")))
return queue_if_no_path(m, 1);
return queue_if_no_path(m, 1, 0);
else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path")))
return queue_if_no_path(m, 0);
return queue_if_no_path(m, 0, 0);
}
if (argc != 2)

View file

@ -100,8 +100,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
printk("DVB: TDA10021(%d): %s: readreg error (ret == %i)\n",
state->frontend.dvb->num, __FUNCTION__, ret);
printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
__FUNCTION__, ret);
return b1[0];
}

View file

@ -140,6 +140,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#if ALLOW_DMA
#include <asm/dma.h>
#endif

View file

@ -67,8 +67,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.40"
#define DRV_MODULE_RELDATE "September 15, 2005"
#define DRV_MODULE_VERSION "3.41"
#define DRV_MODULE_RELDATE "September 27, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@ -3389,7 +3389,8 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
if (sblk->status & SD_STATUS_UPDATED) {
if ((sblk->status & SD_STATUS_UPDATED) ||
!(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
return IRQ_RETVAL(1);
@ -5395,6 +5396,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
struct tg3 *tp = netdev_priv(dev);
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
spin_lock_bh(&tp->lock);
@ -5806,6 +5810,13 @@ static int tg3_reset_hw(struct tg3 *tp)
}
memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
/* reset to prevent losing 1st rx packet intermittently */
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
}
tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
tw32_f(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
@ -5937,7 +5948,7 @@ static int tg3_reset_hw(struct tg3 *tp)
tw32(MAC_LED_CTRL, tp->led_ctrl);
tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
}
@ -7360,12 +7371,17 @@ static int tg3_nway_reset(struct net_device *dev)
if (!netif_running(dev))
return -EAGAIN;
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
return -EINVAL;
spin_lock_bh(&tp->lock);
r = -EINVAL;
tg3_readphy(tp, MII_BMCR, &bmcr);
if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
(bmcr & BMCR_ANENABLE)) {
tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
((bmcr & BMCR_ANENABLE) ||
(tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
BMCR_ANENABLE);
r = 0;
}
spin_unlock_bh(&tp->lock);
@ -7927,19 +7943,32 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
struct tg3_rx_buffer_desc *desc;
if (loopback_mode == TG3_MAC_LOOPBACK) {
/* HW errata - mac loopback fails in some cases on 5780.
* Normal traffic and PHY loopback are not affected by
* errata.
*/
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
return 0;
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY |
MAC_MODE_PORT_MODE_GMII;
tw32(MAC_MODE, mac_mode);
} else if (loopback_mode == TG3_PHY_LOOPBACK) {
tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
BMCR_SPEED1000);
udelay(40);
/* reset to prevent losing 1st rx packet intermittently */
if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tw32_f(MAC_RX_MODE, RX_MODE_RESET);
udelay(10);
tw32_f(MAC_RX_MODE, tp->rx_mode);
}
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)
mac_mode &= ~MAC_MODE_LINK_POLARITY;
tw32(MAC_MODE, mac_mode);
tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
BMCR_SPEED1000);
}
else
return -EINVAL;
@ -10324,6 +10353,44 @@ static char * __devinit tg3_phy_string(struct tg3 *tp)
};
}
static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
{
if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
strcpy(str, "PCI Express");
return str;
} else if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
strcpy(str, "PCIX:");
if ((clock_ctrl == 7) ||
((tr32(GRC_MISC_CFG) & GRC_MISC_CFG_BOARD_ID_MASK) ==
GRC_MISC_CFG_BOARD_ID_5704CIOBE))
strcat(str, "133MHz");
else if (clock_ctrl == 0)
strcat(str, "33MHz");
else if (clock_ctrl == 2)
strcat(str, "50MHz");
else if (clock_ctrl == 4)
strcat(str, "66MHz");
else if (clock_ctrl == 6)
strcat(str, "100MHz");
else if (clock_ctrl == 7)
strcat(str, "133MHz");
} else {
strcpy(str, "PCI:");
if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED)
strcat(str, "66MHz");
else
strcat(str, "33MHz");
}
if (tp->tg3_flags & TG3_FLAG_PCI_32BIT)
strcat(str, ":32-bit");
else
strcat(str, ":64-bit");
return str;
}
static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
{
struct pci_dev *peer;
@ -10386,6 +10453,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
struct net_device *dev;
struct tg3 *tp;
int i, err, pci_using_dac, pm_cap;
char str[40];
if (tg3_version_printed++ == 0)
printk(KERN_INFO "%s", version);
@ -10631,16 +10699,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, dev);
printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ",
printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ",
dev->name,
tp->board_part_number,
tp->pci_chip_rev_id,
tg3_phy_string(tp),
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""),
((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ?
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") :
((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")),
((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"),
tg3_bus_string(tp, str),
(tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000");
for (i = 0; i < 6; i++)

View file

@ -2246,6 +2246,7 @@ struct tg3 {
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
(X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
(X) == PHY_ID_BCM8002)
struct tg3_hw_stats *hw_stats;

View file

@ -2458,7 +2458,6 @@ struct net_device *alloc_orinocodev(int sizeof_card,
dev->watchdog_timeo = HZ; /* 1 second timeout */
dev->get_stats = orinoco_get_stats;
dev->ethtool_ops = &orinoco_ethtool_ops;
dev->get_wireless_stats = orinoco_get_wireless_stats;
dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
dev->change_mtu = orinoco_change_mtu;
dev->set_multicast_list = orinoco_set_multicast_list;
@ -4399,6 +4398,7 @@ static const struct iw_handler_def orinoco_handler_def = {
.standard = orinoco_handler,
.private = orinoco_private_handler,
.private_args = orinoco_privtab,
.get_wireless_stats = orinoco_get_wireless_stats,
};
static void orinoco_get_drvinfo(struct net_device *dev,

View file

@ -146,7 +146,7 @@ config I82365
config TCIC
tristate "Databook TCIC host bridge support"
depends on PCMCIA
depends on PCMCIA && ISA
select PCCARD_NONSTATIC
help
Say Y here to include support for the Databook TCIC family of PCMCIA

View file

@ -228,6 +228,11 @@ int cb_alloc(struct pcmcia_socket * s)
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
cardbus_assign_irqs(bus, s->pci_irq);
/* socket specific tune function */
if (s->tune_bridge)
s->tune_bridge(s, bus);
pci_enable_bridges(bus);
pci_bus_add_devices(bus);

View file

@ -59,6 +59,7 @@
#define TI122X_SCR_SER_STEP 0xc0000000
#define TI122X_SCR_INTRTIE 0x20000000
#define TIXX21_SCR_TIEALL 0x10000000
#define TI122X_SCR_CBRSVD 0x00400000
#define TI122X_SCR_MRBURSTDN 0x00008000
#define TI122X_SCR_MRBURSTUP 0x00004000
@ -153,6 +154,12 @@
/* EnE test register */
#define ENE_TEST_C9 0xc9 /* 8bit */
#define ENE_TEST_C9_TLTENABLE 0x02
#define ENE_TEST_C9_PFENABLE_F0 0x04
#define ENE_TEST_C9_PFENABLE_F1 0x08
#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0)
#define ENE_TEST_C9_WPDISALBLE_F0 0x40
#define ENE_TEST_C9_WPDISALBLE_F1 0x80
#define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1)
/*
* Texas Instruments CardBus controller overrides.
@ -618,6 +625,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
int devfn;
unsigned int state;
int ret = 1;
u32 sysctl;
/* catch the two-slot controllers */
switch (socket->dev->device) {
@ -640,6 +648,24 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
*/
break;
case PCI_DEVICE_ID_TI_X515:
case PCI_DEVICE_ID_TI_X420:
case PCI_DEVICE_ID_TI_X620:
case PCI_DEVICE_ID_TI_XX21_XX11:
case PCI_DEVICE_ID_TI_7410:
case PCI_DEVICE_ID_TI_7610:
/*
* those are either single or dual slot CB with additional functions
* like 1394, smartcard reader, etc. check the TIEALL flag for them
* the TIEALL flag binds the IRQ of all functions toghether.
* we catch the single slot variants later.
*/
sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
if (sysctl & TIXX21_SCR_TIEALL)
return 0;
break;
/* single-slot controllers have the 2nd slot empty always :) */
default:
return 1;
@ -652,6 +678,15 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
if (!func)
return 1;
/*
* check that the device id of both slots match. this is needed for the
* XX21 and the XX11 controller that share the same device id for single
* and dual slot controllers. return '2nd slot empty'. we already checked
* if the interrupt is tied to another function.
*/
if (socket->dev->device != func->device)
goto out;
slot2 = pci_get_drvdata(func);
if (!slot2)
goto out;
@ -790,16 +825,6 @@ static int ti12xx_override(struct yenta_socket *socket)
if (val_orig != val)
config_writel(socket, TI113X_SYSTEM_CONTROL, val);
/*
* for EnE bridges only: clear testbit TLTEnable. this makes the
* RME Hammerfall DSP sound card working.
*/
if (socket->dev->vendor == PCI_VENDOR_ID_ENE) {
u8 test_c9 = config_readb(socket, ENE_TEST_C9);
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
config_writeb(socket, ENE_TEST_C9, test_c9);
}
/*
* Yenta expects controllers to use CSCINT to route
* CSC interrupts to PCI rather than INTVAL.
@ -841,5 +866,75 @@ static int ti1250_override(struct yenta_socket *socket)
return ti12xx_override(socket);
}
/**
* EnE specific part. EnE bridges are register compatible with TI bridges but
* have their own test registers and more important their own little problems.
* Some fixup code to make everybody happy (TM).
*/
/**
* set/clear various test bits:
* Defaults to clear the bit.
* - mask (u8) defines what bits to change
* - bits (u8) is the values to change them to
* -> it's
* current = (current & ~mask) | bits
*/
/* pci ids of devices that wants to have the bit set */
#define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \
.vendor = _vend, \
.device = _dev, \
.subvendor = _subvend, \
.subdevice = _subdev, \
.driver_data = ((mask) << 8 | (bits)), \
}
static struct pci_device_id ene_tune_tbl[] = {
/* Echo Audio products based on motorola DSP56301 and DSP56361 */
DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID,
ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
{}
};
static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
struct pci_dev *dev;
struct pci_device_id *id = NULL;
u8 test_c9, old_c9, mask, bits;
list_for_each_entry(dev, &bus->devices, bus_list) {
id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev);
if (id)
break;
}
test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9);
if (id) {
mask = (id->driver_data >> 8) & 0xFF;
bits = id->driver_data & 0xFF;
test_c9 = (test_c9 & ~mask) | bits;
}
else
/* default to clear TLTEnable bit, old behaviour */
test_c9 &= ~ENE_TEST_C9_TLTENABLE;
printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
config_writeb(socket, ENE_TEST_C9, test_c9);
}
static int ene_override(struct yenta_socket *socket)
{
/* install tune_bridge() function */
socket->socket.tune_bridge = ene_tune_bridge;
return ti1250_override(socket);
}
#endif /* _LINUX_TI113X_H */

View file

@ -559,12 +559,6 @@ static void yenta_interrogate(struct yenta_socket *socket)
static int yenta_sock_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
u16 bridge;
bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
if (!socket->cb_irq)
bridge |= CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge);
exca_writeb(socket, I365_GBLCTL, 0x00);
exca_writeb(socket, I365_GENCTL, 0x00);
@ -819,6 +813,7 @@ enum {
CARDBUS_TYPE_TOPIC95,
CARDBUS_TYPE_TOPIC97,
CARDBUS_TYPE_O2MICRO,
CARDBUS_TYPE_ENE,
};
/*
@ -865,6 +860,12 @@ static struct cardbus_type cardbus_type[] = {
.override = o2micro_override,
.restore_state = o2micro_restore_state,
},
[CARDBUS_TYPE_ENE] = {
.override = ene_override,
.save_state = ti_save_state,
.restore_state = ti_restore_state,
.sock_init = ti_init,
},
};
@ -883,16 +884,8 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
{
int i;
unsigned long val;
u16 bridge_ctrl;
u32 mask;
/* Set up ISA irq routing to probe the ISA irqs.. */
bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
bridge_ctrl |= CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
}
/*
* Probe for usable interrupts using the force
* register to generate bogus card status events.
@ -914,9 +907,6 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
mask = probe_irq_mask(val) & 0xffff;
bridge_ctrl &= ~CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
return mask;
}
@ -944,18 +934,11 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *re
/* probes the PCI interrupt, use only on override functions */
static int yenta_probe_cb_irq(struct yenta_socket *socket)
{
u16 bridge_ctrl;
if (!socket->cb_irq)
return -1;
socket->probe_status = 0;
/* disable ISA interrupts */
bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
bridge_ctrl &= ~CB_BRIDGE_INTR;
config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
if (request_irq(socket->cb_irq, yenta_probe_handler, SA_SHIRQ, "yenta", socket)) {
printk(KERN_WARNING "Yenta: request_irq() in yenta_probe_cb_irq() failed!\n");
return -1;
@ -966,7 +949,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
msleep(100);
/* disable interrupts */
@ -1004,11 +987,12 @@ static void yenta_config_init(struct yenta_socket *socket)
{
u16 bridge;
struct pci_dev *dev = socket->dev;
struct pci_bus_region region;
pci_set_power_state(socket->dev, 0);
pcibios_resource_to_bus(socket->dev, &region, &dev->resource[0]);
config_writel(socket, CB_LEGACY_MODE_BASE, 0);
config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
config_writel(socket, PCI_BASE_ADDRESS_0, region.start);
config_writew(socket, PCI_COMMAND,
PCI_COMMAND_IO |
PCI_COMMAND_MEMORY |
@ -1031,8 +1015,8 @@ static void yenta_config_init(struct yenta_socket *socket)
* - PCI interrupts enabled if a PCI interrupt exists..
*/
bridge = config_readw(socket, CB_BRIDGE_CONTROL);
bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN | CB_BRIDGE_INTR;
bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
config_writew(socket, CB_BRIDGE_CONTROL, bridge);
}
@ -1265,10 +1249,22 @@ static struct pci_device_id yenta_table [] = {
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, TI1250),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X515, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X420, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_X620, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7410, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7510, TI12XX),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_7610, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, TI12XX),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),

View file

@ -859,6 +859,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),

View file

@ -71,21 +71,28 @@ static int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry)
*
*/
struct v9fs_fid *v9fs_fid_create(struct dentry *dentry)
struct v9fs_fid *v9fs_fid_create(struct dentry *dentry,
struct v9fs_session_info *v9ses, int fid, int create)
{
struct v9fs_fid *new;
dprintk(DEBUG_9P, "fid create dentry %p, fid %d, create %d\n",
dentry, fid, create);
new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
if (new == NULL) {
dprintk(DEBUG_ERROR, "Out of Memory\n");
return ERR_PTR(-ENOMEM);
}
new->fid = -1;
new->fid = fid;
new->v9ses = v9ses;
new->fidopen = 0;
new->fidcreate = 0;
new->fidcreate = create;
new->fidclunked = 0;
new->iounit = 0;
new->rdir_pos = 0;
new->rdir_fcall = NULL;
if (v9fs_fid_insert(new, dentry) == 0)
return new;
@ -108,6 +115,59 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
kfree(fid);
}
/**
* v9fs_fid_walk_up - walks from the process current directory
* up to the specified dentry.
*/
static struct v9fs_fid *v9fs_fid_walk_up(struct dentry *dentry)
{
int fidnum, cfidnum, err;
struct v9fs_fid *cfid;
struct dentry *cde;
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(current->fs->pwd->d_inode);
cfid = v9fs_fid_lookup(current->fs->pwd);
if (cfid == NULL) {
dprintk(DEBUG_ERROR, "process cwd doesn't have a fid\n");
return ERR_PTR(-ENOENT);
}
cfidnum = cfid->fid;
cde = current->fs->pwd;
/* TODO: take advantage of multiwalk */
fidnum = v9fs_get_idpool(&v9ses->fidpool);
if (fidnum < 0) {
dprintk(DEBUG_ERROR, "could not get a new fid num\n");
err = -ENOENT;
goto clunk_fid;
}
while (cde != dentry) {
if (cde == cde->d_parent) {
dprintk(DEBUG_ERROR, "can't find dentry\n");
err = -ENOENT;
goto clunk_fid;
}
err = v9fs_t_walk(v9ses, cfidnum, fidnum, "..", NULL);
if (err < 0) {
dprintk(DEBUG_ERROR, "problem walking to parent\n");
goto clunk_fid;
}
cfidnum = fidnum;
cde = cde->d_parent;
}
return v9fs_fid_create(dentry, v9ses, fidnum, 0);
clunk_fid:
v9fs_t_clunk(v9ses, fidnum, NULL);
return ERR_PTR(err);
}
/**
* v9fs_fid_lookup - retrieve the right fid from a particular dentry
* @dentry: dentry to look for fid in
@ -119,49 +179,25 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
*
*/
struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type)
struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
{
struct list_head *fid_list = (struct list_head *)dentry->d_fsdata;
struct v9fs_fid *current_fid = NULL;
struct v9fs_fid *temp = NULL;
struct v9fs_fid *return_fid = NULL;
int found_parent = 0;
int found_user = 0;
dprintk(DEBUG_9P, " dentry: %s (%p) type %d\n", dentry->d_iname, dentry,
type);
dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
if (fid_list && !list_empty(fid_list)) {
if (fid_list) {
list_for_each_entry_safe(current_fid, temp, fid_list, list) {
if (current_fid->uid == current->uid) {
if (return_fid == NULL) {
if ((type == FID_OP)
|| (!current_fid->fidopen)) {
return_fid = current_fid;
found_user = 1;
}
}
}
if (current_fid->pid == current->real_parent->pid) {
if ((return_fid == NULL) || (found_parent)
|| (found_user)) {
if ((type == FID_OP)
|| (!current_fid->fidopen)) {
return_fid = current_fid;
found_parent = 1;
found_user = 0;
}
}
}
if (current_fid->pid == current->pid) {
if ((type == FID_OP) ||
(!current_fid->fidopen)) {
return_fid = current_fid;
found_parent = 0;
found_user = 0;
}
if (!current_fid->fidcreate) {
return_fid = current_fid;
break;
}
}
if (!return_fid)
return_fid = current_fid;
}
/* we are at the root but didn't match */
@ -187,55 +223,33 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type)
/* XXX - there may be some duplication we can get rid of */
if (par == dentry) {
/* we need to fid_lookup the starting point */
int fidnum = -1;
int oldfid = -1;
int result = -1;
struct v9fs_session_info *v9ses =
v9fs_inode2v9ses(current->fs->pwd->d_inode);
current_fid =
v9fs_fid_lookup(current->fs->pwd, FID_WALK);
if (current_fid == NULL) {
dprintk(DEBUG_ERROR,
"process cwd doesn't have a fid\n");
return return_fid;
}
oldfid = current_fid->fid;
par = current->fs->pwd;
/* TODO: take advantage of multiwalk */
fidnum = v9fs_get_idpool(&v9ses->fidpool);
if (fidnum < 0) {
dprintk(DEBUG_ERROR,
"could not get a new fid num\n");
return return_fid;
}
while (par != dentry) {
result =
v9fs_t_walk(v9ses, oldfid, fidnum, "..",
NULL);
if (result < 0) {
dprintk(DEBUG_ERROR,
"problem walking to parent\n");
break;
}
oldfid = fidnum;
if (par == par->d_parent) {
dprintk(DEBUG_ERROR,
"can't find dentry\n");
break;
}
par = par->d_parent;
}
if (par == dentry) {
return_fid = v9fs_fid_create(dentry);
return_fid->fid = fidnum;
}
return_fid = v9fs_fid_walk_up(dentry);
if (IS_ERR(return_fid))
return_fid = NULL;
}
}
return return_fid;
}
struct v9fs_fid *v9fs_fid_get_created(struct dentry *dentry)
{
struct list_head *fid_list;
struct v9fs_fid *fid, *ftmp, *ret;
dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry);
fid_list = (struct list_head *)dentry->d_fsdata;
ret = NULL;
if (fid_list) {
list_for_each_entry_safe(fid, ftmp, fid_list, list) {
if (fid->fidcreate && fid->pid == current->pid) {
list_del(&fid->list);
ret = fid;
break;
}
}
}
dprintk(DEBUG_9P, "return %p\n", ret);
return ret;
}

View file

@ -25,6 +25,7 @@
#define FID_OP 0
#define FID_WALK 1
#define FID_CREATE 2
struct v9fs_fid {
struct list_head list; /* list of fids associated with a dentry */
@ -52,6 +53,8 @@ struct v9fs_fid {
struct v9fs_session_info *v9ses; /* session info for this FID */
};
struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry, int type);
struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry);
struct v9fs_fid *v9fs_fid_get_created(struct dentry *);
void v9fs_fid_destroy(struct v9fs_fid *fid);
struct v9fs_fid *v9fs_fid_create(struct dentry *);
struct v9fs_fid *v9fs_fid_create(struct dentry *,
struct v9fs_session_info *v9ses, int fid, int create);

View file

@ -67,7 +67,7 @@ static int v9fs_dentry_validate(struct dentry *dentry, struct nameidata *nd)
struct dentry *dc = current->fs->pwd;
dprintk(DEBUG_VFS, "dentry: %s (%p)\n", dentry->d_iname, dentry);
if (v9fs_fid_lookup(dentry, FID_OP)) {
if (v9fs_fid_lookup(dentry)) {
dprintk(DEBUG_VFS, "VALID\n");
return 1;
}

View file

@ -197,21 +197,18 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
filemap_fdatawait(inode->i_mapping);
if (fidnum >= 0) {
fid->fidopen--;
dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
fid->fid);
if (fid->fidopen == 0) {
if (v9fs_t_clunk(v9ses, fidnum, NULL))
dprintk(DEBUG_ERROR, "clunk failed\n");
if (v9fs_t_clunk(v9ses, fidnum, NULL))
dprintk(DEBUG_ERROR, "clunk failed\n");
v9fs_put_idpool(fid->fid, &v9ses->fidpool);
}
v9fs_put_idpool(fid->fid, &v9ses->fidpool);
kfree(fid->rdir_fcall);
kfree(fid);
filp->private_data = NULL;
v9fs_fid_destroy(fid);
}
d_drop(filp->f_dentry);

View file

@ -53,30 +53,36 @@
int v9fs_file_open(struct inode *inode, struct file *file)
{
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
struct v9fs_fid *v9fid = v9fs_fid_lookup(file->f_dentry, FID_WALK);
struct v9fs_fid *v9newfid = NULL;
struct v9fs_fid *v9fid, *fid;
struct v9fs_fcall *fcall = NULL;
int open_mode = 0;
unsigned int iounit = 0;
int newfid = -1;
long result = -1;
dprintk(DEBUG_VFS, "inode: %p file: %p v9fid= %p\n", inode, file,
v9fid);
dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);
v9fid = v9fs_fid_get_created(file->f_dentry);
if (!v9fid)
v9fid = v9fs_fid_lookup(file->f_dentry);
if (!v9fid) {
struct dentry *dentry = file->f_dentry;
dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n");
return -EBADF;
}
/* XXX - some duplication from lookup, generalize later */
/* basically vfs_lookup is too heavy weight */
v9fid = v9fs_fid_lookup(file->f_dentry, FID_OP);
if (!v9fid)
return -EBADF;
if (!v9fid->fidcreate) {
fid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
if (fid == NULL) {
dprintk(DEBUG_ERROR, "Out of Memory\n");
return -ENOMEM;
}
v9fid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
if (!v9fid)
return -EBADF;
fid->fidopen = 0;
fid->fidcreate = 0;
fid->fidclunked = 0;
fid->iounit = 0;
fid->v9ses = v9ses;
newfid = v9fs_get_idpool(&v9ses->fidpool);
if (newfid < 0) {
@ -85,58 +91,16 @@ int v9fs_file_open(struct inode *inode, struct file *file)
}
result =
v9fs_t_walk(v9ses, v9fid->fid, newfid,
(char *)file->f_dentry->d_name.name, NULL);
v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL, NULL);
if (result < 0) {
v9fs_put_idpool(newfid, &v9ses->fidpool);
dprintk(DEBUG_ERROR, "rewalk didn't work\n");
return -EBADF;
}
v9fid = v9fs_fid_create(dentry);
if (v9fid == NULL) {
dprintk(DEBUG_ERROR, "couldn't insert\n");
return -ENOMEM;
}
v9fid->fid = newfid;
}
if (v9fid->fidcreate) {
/* create case */
newfid = v9fid->fid;
iounit = v9fid->iounit;
v9fid->fidcreate = 0;
} else {
if (!S_ISDIR(inode->i_mode))
newfid = v9fid->fid;
else {
newfid = v9fs_get_idpool(&v9ses->fidpool);
if (newfid < 0) {
eprintk(KERN_WARNING, "allocation failed\n");
return -ENOSPC;
}
/* This would be a somewhat critical clone */
result =
v9fs_t_walk(v9ses, v9fid->fid, newfid, NULL,
&fcall);
if (result < 0) {
dprintk(DEBUG_ERROR, "clone error: %s\n",
FCALL_ERROR(fcall));
kfree(fcall);
return result;
}
v9newfid = v9fs_fid_create(file->f_dentry);
v9newfid->fid = newfid;
v9newfid->qid = v9fid->qid;
v9newfid->iounit = v9fid->iounit;
v9newfid->fidopen = 0;
v9newfid->fidclunked = 0;
v9newfid->v9ses = v9ses;
v9fid = v9newfid;
kfree(fcall);
}
fid->fid = newfid;
v9fid = fid;
/* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
/* translate open mode appropriately */
open_mode = file->f_flags & 0x3;
@ -163,9 +127,13 @@ int v9fs_file_open(struct inode *inode, struct file *file)
iounit = fcall->params.ropen.iounit;
kfree(fcall);
} else {
/* create case */
newfid = v9fid->fid;
iounit = v9fid->iounit;
v9fid->fidcreate = 0;
}
file->private_data = v9fid;
v9fid->rdir_pos = 0;

View file

@ -307,7 +307,7 @@ v9fs_create(struct inode *dir,
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
struct super_block *sb = dir->i_sb;
struct v9fs_fid *dirfid =
v9fs_fid_lookup(file_dentry->d_parent, FID_WALK);
v9fs_fid_lookup(file_dentry->d_parent);
struct v9fs_fid *fid = NULL;
struct inode *file_inode = NULL;
struct v9fs_fcall *fcall = NULL;
@ -317,6 +317,7 @@ v9fs_create(struct inode *dir,
long newfid = -1;
int result = 0;
unsigned int iounit = 0;
int wfidno = -1;
perm = unixmode2p9mode(v9ses, perm);
@ -350,7 +351,7 @@ v9fs_create(struct inode *dir,
if (result < 0) {
dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
v9fs_put_idpool(newfid, &v9ses->fidpool);
newfid = 0;
newfid = -1;
goto CleanUpFid;
}
@ -369,20 +370,39 @@ v9fs_create(struct inode *dir,
qid = fcall->params.rcreate.qid;
kfree(fcall);
fid = v9fs_fid_create(file_dentry);
fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
if (!fid) {
result = -ENOMEM;
goto CleanUpFid;
}
fid->fid = newfid;
fid->fidopen = 0;
fid->fidcreate = 1;
fid->qid = qid;
fid->iounit = iounit;
fid->rdir_pos = 0;
fid->rdir_fcall = NULL;
fid->v9ses = v9ses;
/* walk to the newly created file and put the fid in the dentry */
wfidno = v9fs_get_idpool(&v9ses->fidpool);
if (newfid < 0) {
eprintk(KERN_WARNING, "no free fids available\n");
return -ENOSPC;
}
result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
(char *) file_dentry->d_name.name, NULL);
if (result < 0) {
dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
v9fs_put_idpool(wfidno, &v9ses->fidpool);
wfidno = -1;
goto CleanUpFid;
}
if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
if (!v9fs_t_clunk(v9ses, newfid, &fcall)) {
v9fs_put_idpool(wfidno, &v9ses->fidpool);
}
goto CleanUpFid;
}
if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) ||
(perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) ||
@ -410,11 +430,11 @@ v9fs_create(struct inode *dir,
d_instantiate(file_dentry, file_inode);
if (perm & V9FS_DMDIR) {
if (v9fs_t_clunk(v9ses, newfid, &fcall))
if (!v9fs_t_clunk(v9ses, newfid, &fcall))
v9fs_put_idpool(newfid, &v9ses->fidpool);
else
dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
FCALL_ERROR(fcall));
v9fs_put_idpool(newfid, &v9ses->fidpool);
kfree(fcall);
fid->fidopen = 0;
fid->fidcreate = 0;
@ -426,12 +446,22 @@ v9fs_create(struct inode *dir,
CleanUpFid:
kfree(fcall);
if (newfid) {
if (v9fs_t_clunk(v9ses, newfid, &fcall))
if (newfid >= 0) {
if (!v9fs_t_clunk(v9ses, newfid, &fcall))
v9fs_put_idpool(newfid, &v9ses->fidpool);
else
dprintk(DEBUG_ERROR, "clunk failed: %s\n",
FCALL_ERROR(fcall));
kfree(fcall);
}
if (wfidno >= 0) {
if (!v9fs_t_clunk(v9ses, wfidno, &fcall))
v9fs_put_idpool(wfidno, &v9ses->fidpool);
else
dprintk(DEBUG_ERROR, "clunk failed: %s\n",
FCALL_ERROR(fcall));
v9fs_put_idpool(newfid, &v9ses->fidpool);
kfree(fcall);
}
return result;
@ -461,7 +491,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
file_inode = file->d_inode;
sb = file_inode->i_sb;
v9ses = v9fs_inode2v9ses(file_inode);
v9fid = v9fs_fid_lookup(file, FID_OP);
v9fid = v9fs_fid_lookup(file);
if (!v9fid) {
dprintk(DEBUG_ERROR,
@ -545,7 +575,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
sb = dir->i_sb;
v9ses = v9fs_inode2v9ses(dir);
dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK);
dirfid = v9fs_fid_lookup(dentry->d_parent);
if (!dirfid) {
dprintk(DEBUG_ERROR, "no dirfid\n");
@ -573,7 +603,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
v9fs_put_idpool(newfid, &v9ses->fidpool);
if (result == -ENOENT) {
d_add(dentry, NULL);
dprintk(DEBUG_ERROR,
dprintk(DEBUG_VFS,
"Return negative dentry %p count %d\n",
dentry, atomic_read(&dentry->d_count));
return NULL;
@ -601,16 +631,13 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
fid = v9fs_fid_create(dentry);
fid = v9fs_fid_create(dentry, v9ses, newfid, 0);
if (fid == NULL) {
dprintk(DEBUG_ERROR, "couldn't insert\n");
result = -ENOMEM;
goto FreeFcall;
}
fid->fid = newfid;
fid->fidopen = 0;
fid->v9ses = v9ses;
fid->qid = fcall->params.rstat.stat->qid;
dentry->d_op = &v9fs_dentry_operations;
@ -665,11 +692,11 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
{
struct inode *old_inode = old_dentry->d_inode;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK);
struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
struct v9fs_fid *olddirfid =
v9fs_fid_lookup(old_dentry->d_parent, FID_WALK);
v9fs_fid_lookup(old_dentry->d_parent);
struct v9fs_fid *newdirfid =
v9fs_fid_lookup(new_dentry->d_parent, FID_WALK);
v9fs_fid_lookup(new_dentry->d_parent);
struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
struct v9fs_fcall *fcall = NULL;
int fid = -1;
@ -744,7 +771,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
{
struct v9fs_fcall *fcall = NULL;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
int err = -EPERM;
dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
@ -778,7 +805,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
{
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
struct v9fs_fcall *fcall = NULL;
struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
int res = -EPERM;
@ -960,7 +987,7 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
if (retval != 0)
goto FreeFcall;
newfid = v9fs_fid_lookup(dentry, FID_OP);
newfid = v9fs_fid_lookup(dentry);
/* issue a twstat */
v9fs_blank_mistat(v9ses, mistat);
@ -1004,7 +1031,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
struct v9fs_fcall *fcall = NULL;
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP);
struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
if (!fid) {
dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n");
@ -1148,7 +1175,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
struct v9fs_fcall *fcall = NULL;
struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP);
struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
struct v9fs_fid *newfid = NULL;
char *symname = __getname();
@ -1168,7 +1195,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
if (retval != 0)
goto FreeMem;
newfid = v9fs_fid_lookup(dentry, FID_OP);
newfid = v9fs_fid_lookup(dentry);
if (!newfid) {
dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
goto FreeMem;
@ -1246,7 +1273,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
if (retval != 0)
goto FreeMem;
newfid = v9fs_fid_lookup(dentry, FID_OP);
newfid = v9fs_fid_lookup(dentry);
if (!newfid) {
dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
retval = -EINVAL;

View file

@ -129,8 +129,7 @@ static struct super_block *v9fs_get_sb(struct file_system_type
if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
dprintk(DEBUG_ERROR, "problem initiating session\n");
kfree(v9ses);
return ERR_PTR(newfid);
return newfid;
}
sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
@ -155,23 +154,19 @@ static struct super_block *v9fs_get_sb(struct file_system_type
sb->s_root = root;
/* Setup the Root Inode */
root_fid = v9fs_fid_create(root);
if (root_fid == NULL) {
retval = -ENOMEM;
goto put_back_sb;
}
root_fid->fidopen = 0;
root_fid->v9ses = v9ses;
stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
if (stat_result < 0) {
dprintk(DEBUG_ERROR, "stat error\n");
v9fs_t_clunk(v9ses, newfid, NULL);
v9fs_put_idpool(newfid, &v9ses->fidpool);
} else {
root_fid->fid = newfid;
/* Setup the Root Inode */
root_fid = v9fs_fid_create(root, v9ses, newfid, 0);
if (root_fid == NULL) {
retval = -ENOMEM;
goto put_back_sb;
}
root_fid->qid = fcall->params.rstat.stat->qid;
root->d_inode->i_ino =
v9fs_qid2ino(&fcall->params.rstat.stat->qid);

View file

@ -472,6 +472,9 @@ config FUSE_FS
utilities is available from the FUSE homepage:
<http://fuse.sourceforge.net/>
See <file:Documentation/filesystems/fuse.txt> for more information.
See <file:Documentation/Changes> for needed library/utility version.
If you want to develop a userspace FS, or if you want to use
a filesystem based on FUSE, answer Y or M.

View file

@ -101,6 +101,10 @@
/* Maximum number of poll wake up nests we are allowing */
#define EP_MAX_POLLWAKE_NESTS 4
/* Maximum msec timeout value storeable in a long int */
#define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
struct epoll_filefd {
struct file *file;
int fd;
@ -1506,8 +1510,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
* and the overflow condition. The passed timeout is in milliseconds,
* that why (t * HZ) / 1000.
*/
jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ?
MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000;
jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ?
MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000;
retry:
write_lock_irqsave(&ep->lock, flags);

View file

@ -605,27 +605,28 @@ got:
insert_inode_hash(inode);
if (DQUOT_ALLOC_INODE(inode)) {
DQUOT_DROP(inode);
err = -ENOSPC;
goto fail2;
goto fail_drop;
}
err = ext2_init_acl(inode, dir);
if (err) {
DQUOT_FREE_INODE(inode);
DQUOT_DROP(inode);
goto fail2;
}
if (err)
goto fail_free_drop;
err = ext2_init_security(inode,dir);
if (err) {
DQUOT_FREE_INODE(inode);
goto fail2;
}
if (err)
goto fail_free_drop;
mark_inode_dirty(inode);
ext2_debug("allocating inode %lu\n", inode->i_ino);
ext2_preread_inode(inode);
return inode;
fail2:
fail_free_drop:
DQUOT_FREE_INODE(inode);
fail_drop:
DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);

View file

@ -597,27 +597,22 @@ got:
ret = inode;
if(DQUOT_ALLOC_INODE(inode)) {
DQUOT_DROP(inode);
err = -EDQUOT;
goto fail2;
goto fail_drop;
}
err = ext3_init_acl(handle, inode, dir);
if (err) {
DQUOT_FREE_INODE(inode);
DQUOT_DROP(inode);
goto fail2;
}
if (err)
goto fail_free_drop;
err = ext3_init_security(handle,inode, dir);
if (err) {
DQUOT_FREE_INODE(inode);
goto fail2;
}
if (err)
goto fail_free_drop;
err = ext3_mark_inode_dirty(handle, inode);
if (err) {
ext3_std_error(sb, err);
DQUOT_FREE_INODE(inode);
DQUOT_DROP(inode);
goto fail2;
goto fail_free_drop;
}
ext3_debug("allocating inode %lu\n", inode->i_ino);
@ -631,7 +626,11 @@ really_out:
brelse(bitmap_bh);
return ret;
fail2:
fail_free_drop:
DQUOT_FREE_INODE(inode);
fail_drop:
DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);

Some files were not shown because too many files have changed in this diff Show more