diff options
author | Mika Laitio <lamikr@cc.jyu.fi> | 2006-05-21 18:59:07 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-05-21 18:59:07 +0000 |
commit | f97666d21c5c841f23fbbe5c3449cc6f879ba404 (patch) | |
tree | 6ff43ab3696543bdf1771c2091aba62c88a8dca1 /packages/linux/linux-h6300-omap1-2.6.16.16 | |
parent | d7fc2013b1458e14894602621a422eab3f0f9d7c (diff) |
gomunicator: h6300 kernel 2.6.16.16, Tux can now call home.
Diffstat (limited to 'packages/linux/linux-h6300-omap1-2.6.16.16')
4 files changed, 10428 insertions, 0 deletions
diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty b/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-h6300-omap1-2.6.16.16/.mtn2git_empty diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig b/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig new file mode 100644 index 0000000000..ddfa1eb8e6 --- /dev/null +++ b/packages/linux/linux-h6300-omap1-2.6.16.16/defconfig @@ -0,0 +1,1558 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.16.16-omap1-h6300 +# Thu May 18 02:10:05 2006 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_SLAB=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set +CONFIG_OBSOLETE_INTERMODULE=m + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set + +# +# TI OMAP Implementations +# +CONFIG_ARCH_OMAP1=y +# CONFIG_ARCH_OMAP2 is not set + +# +# OMAP Feature Selections +# +# CONFIG_OMAP_RESET_CLOCKS is not set +# CONFIG_OMAP_BOOT_TAG is not set +CONFIG_OMAP_MUX=y +# CONFIG_OMAP_MUX_DEBUG is not set +CONFIG_OMAP_MUX_WARNINGS=y +CONFIG_OMAP_MPU_TIMER=y +# CONFIG_OMAP_32K_TIMER is not set +CONFIG_OMAP_LL_DEBUG_UART1=y +# CONFIG_OMAP_LL_DEBUG_UART2 is not set +# CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_SERIAL_WAKE=y + +# +# OMAP Core Type +# +# CONFIG_ARCH_OMAP730 is not set +CONFIG_ARCH_OMAP15XX=y +# CONFIG_ARCH_OMAP16XX is not set + +# +# OMAP Board Type +# +# CONFIG_MACH_OMAP_INNOVATOR is not set +CONFIG_MACH_OMAP_H6300=y +# CONFIG_MACH_VOICEBLUE is not set +# CONFIG_MACH_OMAP_PALMTE is not set +# CONFIG_MACH_AMS_DELTA is not set +# CONFIG_MACH_OMAP_GENERIC is not set + +# +# OMAP CPU Speed +# +# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set +CONFIG_OMAP_ARM_168MHZ=y +CONFIG_OMAP_ARM_150MHZ=y +CONFIG_OMAP_ARM_120MHZ=y +CONFIG_OMAP_ARM_60MHZ=y +CONFIG_OMAP_ARM_30MHZ=y +CONFIG_OMAP_DSP=y +CONFIG_OMAP_DSP_MBCMD_VERBOSE=y +CONFIG_OMAP_DSP_TASK_MULTIOPEN=y +CONFIG_OMAP_DSP_FBEXPORT=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM925T=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4T=y +CONFIG_CPU_CACHE_V4WT=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +CONFIG_CPU_DCACHE_WRITETHROUGH=y + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_IOCTL=y + +# +# PC-card bridges +# + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +# CONFIG_AEABI 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_SPLIT_PTLOCK_CPUS=4096 +CONFIG_LEDS=y +CONFIG_LEDS_TIMER=y +CONFIG_LEDS_CPU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=tty0 root=/dev/nfs nfsroot=192.168.2.1:/opt/h6300/rootfs,rsize=8192,wsize=8192 ip=192.168.2.2:192.168.2.1:192.168.2.1:255.0.0.0:ipaq:" +# CONFIG_XIP_KERNEL is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +CONFIG_FPE_NWFPE_XP=y +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +CONFIG_BINFMT_MISC=y +# CONFIG_ARTHUR is not set + +# +# Power management options +# +CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set +CONFIG_APM=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +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 is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_XTABLES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +CONFIG_IP_NF_QUEUE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +# CONFIG_BRIDGE_EBT_BROUTE is not set +# CONFIG_BRIDGE_EBT_T_FILTER is not set +# CONFIG_BRIDGE_EBT_T_NAT is not set +# CONFIG_BRIDGE_EBT_802_3 is not set +# CONFIG_BRIDGE_EBT_AMONG is not set +# CONFIG_BRIDGE_EBT_ARP is not set +# CONFIG_BRIDGE_EBT_IP is not set +# CONFIG_BRIDGE_EBT_LIMIT is not set +# CONFIG_BRIDGE_EBT_MARK is not set +# CONFIG_BRIDGE_EBT_PKTTYPE is not set +# CONFIG_BRIDGE_EBT_STP is not set +# CONFIG_BRIDGE_EBT_VLAN is not set +# CONFIG_BRIDGE_EBT_ARPREPLY is not set +# CONFIG_BRIDGE_EBT_DNAT is not set +# CONFIG_BRIDGE_EBT_MARK_T is not set +# CONFIG_BRIDGE_EBT_REDIRECT is not set +# CONFIG_BRIDGE_EBT_SNAT is not set +# CONFIG_BRIDGE_EBT_LOG is not set +# CONFIG_BRIDGE_EBT_ULOG is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_OMAP_IR is not set +CONFIG_BT=m +CONFIG_BT_L2CAP=m +# CONFIG_BT_SCO is not set +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIUSB is not set +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIDTL1 is not set +# CONFIG_BT_HCIBT3C is not set +# CONFIG_BT_HCIBLUECARD is not set +# CONFIG_BT_HCIBTUART is not set +# CONFIG_BT_HCIBRF6150 is not set +CONFIG_BT_HCIVHCI=m +CONFIG_BT_H6300=m +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=m +CONFIG_MTD_CFI_AMDSTD=m +CONFIG_MTD_CFI_AMDSTD_RETRY=1 +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +CONFIG_MTD_ABSENT=m +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_OMAP_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_MTDRAM=m +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTD_BLKMTD=m +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE_ADVANCED=y +CONFIG_MTD_DOCPROBE_ADDRESS=0x0000 +CONFIG_MTD_DOCPROBE_HIGH=y +CONFIG_MTD_DOCPROBE_55AA=y + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_TOTO is not set +CONFIG_MTD_NAND_IDS=m +CONFIG_MTD_NAND_DISKONCHIP=m +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH is not set +CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_ONENAND_SYNC_READ is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +CONFIG_STRIP=y +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_HERMES is not set +CONFIG_ATMEL=y + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_ATMEL is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +# CONFIG_PPP_MPPE is not set +CONFIG_PPPOE=y +# 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 +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_TSDEV=y +CONFIG_INPUT_TSDEV_SCREEN_X=240 +CONFIG_INPUT_TSDEV_SCREEN_Y=320 +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_KEYBOARD_OMAP=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_SERIAL=y +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +CONFIG_TOUCHSCREEN_OMAP=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=y +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_CS is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_NVRAM=y +# CONFIG_RTC is not set +CONFIG_OMAP_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA_ISA is not set +CONFIG_I2C_OMAP=y + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +CONFIG_PCA9535=y +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_TPS65010 is not set +# CONFIG_SENSORS_TLV320AIC23 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C 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 + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 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_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# 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_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 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 +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set +CONFIG_FB_OMAP=y +# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set +# CONFIG_FB_OMAP_LCD_LPH8923 is not set +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set +CONFIG_FB_OMAP_DMA_TUNE=y +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FONTS=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_MINI_4x6=y +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_10x18 is not set + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +CONFIG_LOGO_LINUX_VGA16=y +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y + +# +# Telephony Support +# +CONFIG_PHONE=m +# CONFIG_PHONE_IXJ is not set +CONFIG_GSM_H6300=m + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PRINTK=y +CONFIG_SND_DEBUG=y +# CONFIG_SND_DEBUG_DETECT is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +# CONFIG_SND_OMAP_AIC23 is not set +CONFIG_SND_OMAP_TSC2101=m + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +CONFIG_USB_DEBUG=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_SUSPEND is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +CONFIG_USB_ACM=y +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +CONFIG_USB_USBNET=y +CONFIG_USB_NET_AX8817X=y +CONFIG_USB_NET_CDCETHER=y +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=y +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +CONFIG_USB_NET_ZAURUS=y +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ANYDATA is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=y +CONFIG_USB_SERIAL_IPAQ=y +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_OMAP=y +CONFIG_USB_OMAP=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=y +# CONFIG_USB_ETH_RNDIS is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BROKEN_RFD=y +CONFIG_MMC_BULKTRANSFER=y +CONFIG_MMC_OMAP=y + +# +# Synchronous Serial Interfaces (SSI) +# +CONFIG_OMAP_UWIRE=y +CONFIG_OMAP_TSC2101=y + +# +# CBUS support +# +# CONFIG_CBUS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +CONFIG_JFFS_PROC_FS=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=4 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +CONFIG_JFFS2_RUBIN=y +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# 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 +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch new file mode 100644 index 0000000000..ff0aaaac27 --- /dev/null +++ b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-2.6.16.16.patch @@ -0,0 +1,5134 @@ +diff -Naur linux-2.6.16/arch/alpha/kernel/setup.c linux-2.6.16.16/arch/alpha/kernel/setup.c +--- linux-2.6.16/arch/alpha/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/alpha/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 +@@ -24,6 +24,7 @@ + #include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ + #include <linux/mc146818rtc.h> + #include <linux/console.h> ++#include <linux/cpu.h> + #include <linux/errno.h> + #include <linux/init.h> + #include <linux/string.h> +@@ -477,6 +478,22 @@ + #undef PFN_PHYS + #undef PFN_MAX + ++static int __init ++register_cpus(void) ++{ ++ int i; ++ ++ for_each_possible_cpu(i) { ++ struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); ++ if (!p) ++ return -ENOMEM; ++ register_cpu(p, i, NULL); ++ } ++ return 0; ++} ++ ++arch_initcall(register_cpus); ++ + void __init + setup_arch(char **cmdline_p) + { +diff -Naur linux-2.6.16/arch/alpha/kernel/smp.c linux-2.6.16.16/arch/alpha/kernel/smp.c +--- linux-2.6.16/arch/alpha/kernel/smp.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/alpha/kernel/smp.c 2006-05-11 04:56:24.000000000 +0300 +@@ -439,7 +439,7 @@ + if ((cpu->flags & 0x1cc) == 0x1cc) { + smp_num_probed++; + /* Assume here that "whami" == index */ +- cpu_set(i, cpu_possible_map); ++ cpu_set(i, cpu_present_mask); + cpu->pal_revision = boot_cpu_palrev; + } + +@@ -450,9 +450,8 @@ + } + } else { + smp_num_probed = 1; +- cpu_set(boot_cpuid, cpu_possible_map); ++ cpu_set(boot_cpuid, cpu_present_mask); + } +- cpu_present_mask = cpumask_of_cpu(boot_cpuid); + + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", + smp_num_probed, cpu_possible_map.bits[0]); +@@ -488,9 +487,8 @@ + smp_prepare_boot_cpu(void) + { + /* +- * Mark the boot cpu (current cpu) as both present and online ++ * Mark the boot cpu (current cpu) as online + */ +- cpu_set(smp_processor_id(), cpu_present_mask); + cpu_set(smp_processor_id(), cpu_online_map); + } + +diff -Naur linux-2.6.16/arch/alpha/lib/strncpy.S linux-2.6.16.16/arch/alpha/lib/strncpy.S +--- linux-2.6.16/arch/alpha/lib/strncpy.S 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/alpha/lib/strncpy.S 2006-05-11 04:56:24.000000000 +0300 +@@ -43,8 +43,8 @@ + + .align 4 + $multiword: +- subq $24, 1, $2 # clear the final bits in the prev word +- or $2, $24, $2 ++ subq $27, 1, $2 # clear the final bits in the prev word ++ or $2, $27, $2 + zapnot $1, $2, $1 + subq $18, 1, $18 + +@@ -70,8 +70,8 @@ + bne $18, 0b + + 1: ldq_u $1, 0($16) # clear the leading bits in the final word +- subq $27, 1, $2 +- or $2, $27, $2 ++ subq $24, 1, $2 ++ or $2, $24, $2 + + zap $1, $2, $1 + stq_u $1, 0($16) +diff -Naur linux-2.6.16/arch/i386/kernel/apm.c linux-2.6.16.16/arch/i386/kernel/apm.c +--- linux-2.6.16/arch/i386/kernel/apm.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/apm.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1081,7 +1081,7 @@ + break; + } + +- if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { ++ if (error == APM_NOT_ENGAGED) { + static int tried; + int eng_error; + if (tried++ == 0) { +diff -Naur linux-2.6.16/arch/i386/kernel/cpu/amd.c linux-2.6.16.16/arch/i386/kernel/cpu/amd.c +--- linux-2.6.16/arch/i386/kernel/cpu/amd.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/cpu/amd.c 2006-05-11 04:56:24.000000000 +0300 +@@ -207,6 +207,8 @@ + set_bit(X86_FEATURE_K7, c->x86_capability); + break; + } ++ if (c->x86 >= 6) ++ set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability); + + display_cacheinfo(c); + +diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig +--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/Kconfig 2006-05-11 04:56:24.000000000 +0300 +@@ -203,6 +203,7 @@ + config X86_LONGHAUL + tristate "VIA Cyrix III Longhaul" + select CPU_FREQ_TABLE ++ depends on BROKEN + help + This adds the CPUFreq driver for VIA Samuel/CyrixIII, + VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T +diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2006-05-11 04:56:24.000000000 +0300 +@@ -244,7 +244,7 @@ + for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) { + if ((i<2) && (has_N44_O17_errata[policy->cpu])) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; +- else if (has_N60_errata[policy->cpu] && p4clockmod_table[i].frequency < 2000000) ++ else if (has_N60_errata[policy->cpu] && ((stock_freq * i)/8) < 2000000) + p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID; + else + p4clockmod_table[i].frequency = (stock_freq * i)/8; +diff -Naur linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +--- linux-2.6.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2006-05-11 04:56:24.000000000 +0300 +@@ -75,7 +75,9 @@ + __asm__ __volatile__( + "out %%al, (%%dx)\n" + : "=D" (result) +- : "a" (command), "b" (function), "c" (0), "d" (smi_port), "D" (0), "S" (magic) ++ : "a" (command), "b" (function), "c" (0), "d" (smi_port), ++ "D" (0), "S" (magic) ++ : "memory" + ); + + dprintk("result is %x\n", result); +diff -Naur linux-2.6.16/arch/i386/kernel/dmi_scan.c linux-2.6.16.16/arch/i386/kernel/dmi_scan.c +--- linux-2.6.16/arch/i386/kernel/dmi_scan.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/dmi_scan.c 2006-05-11 04:56:24.000000000 +0300 +@@ -106,7 +106,7 @@ + struct dmi_device *dev; + + for (i = 0; i < count; i++) { +- char *d = ((char *) dm) + (i * 2); ++ char *d = (char *)(dm + 1) + (i * 2); + + /* Skip disabled device */ + if ((*d & 0x80) == 0) +diff -Naur linux-2.6.16/arch/i386/kernel/vm86.c linux-2.6.16.16/arch/i386/kernel/vm86.c +--- linux-2.6.16/arch/i386/kernel/vm86.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/i386/kernel/vm86.c 2006-05-11 04:56:24.000000000 +0300 +@@ -43,6 +43,7 @@ + #include <linux/smp_lock.h> + #include <linux/highmem.h> + #include <linux/ptrace.h> ++#include <linux/audit.h> + + #include <asm/uaccess.h> + #include <asm/io.h> +@@ -252,6 +253,7 @@ + static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) + { + struct tss_struct *tss; ++ long eax; + /* + * make sure the vm86() system call doesn't try to do anything silly + */ +@@ -305,13 +307,19 @@ + tsk->thread.screen_bitmap = info->screen_bitmap; + if (info->flags & VM86_SCREEN_BITMAP) + mark_screen_rdonly(tsk->mm); ++ __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); ++ __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); ++ ++ /*call audit_syscall_exit since we do not exit via the normal paths */ ++ if (unlikely(current->audit_context)) ++ audit_syscall_exit(current, AUDITSC_RESULT(eax), eax); ++ + __asm__ __volatile__( +- "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t" + "movl %0,%%esp\n\t" + "movl %1,%%ebp\n\t" + "jmp resume_userspace" + : /* no outputs */ +- :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax"); ++ :"r" (&info->regs), "r" (task_thread_info(tsk))); + /* we never return here */ + } + +diff -Naur linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c +--- linux-2.6.16/arch/m32r/kernel/m32r_ksyms.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/kernel/m32r_ksyms.c 2006-05-11 04:56:24.000000000 +0300 +@@ -38,10 +38,6 @@ + EXPORT_SYMBOL(__delay); + EXPORT_SYMBOL(__const_udelay); + +-EXPORT_SYMBOL(__get_user_1); +-EXPORT_SYMBOL(__get_user_2); +-EXPORT_SYMBOL(__get_user_4); +- + EXPORT_SYMBOL(strpbrk); + EXPORT_SYMBOL(strstr); + +diff -Naur linux-2.6.16/arch/m32r/kernel/setup.c linux-2.6.16.16/arch/m32r/kernel/setup.c +--- linux-2.6.16/arch/m32r/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 +@@ -9,6 +9,7 @@ + + #include <linux/config.h> + #include <linux/init.h> ++#include <linux/kernel.h> + #include <linux/stddef.h> + #include <linux/fs.h> + #include <linux/sched.h> +@@ -218,8 +219,6 @@ + extern unsigned long setup_memory(void); + #endif /* CONFIG_DISCONTIGMEM */ + +-#define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */ +- + void __init setup_arch(char **cmdline_p) + { + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); +@@ -268,15 +267,14 @@ + paging_init(); + } + +-static struct cpu cpu[NR_CPUS]; ++static struct cpu cpu_devices[NR_CPUS]; + + static int __init topology_init(void) + { +- int cpu_id; ++ int i; + +- for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) +- if (cpu_possible(cpu_id)) +- register_cpu(&cpu[cpu_id], cpu_id, NULL); ++ for_each_present_cpu(i) ++ register_cpu(&cpu_devices[i], i, NULL); + + return 0; + } +diff -Naur linux-2.6.16/arch/m32r/kernel/smpboot.c linux-2.6.16.16/arch/m32r/kernel/smpboot.c +--- linux-2.6.16/arch/m32r/kernel/smpboot.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/kernel/smpboot.c 2006-05-11 04:56:24.000000000 +0300 +@@ -39,8 +39,10 @@ + * Martin J. Bligh : Added support for multi-quad systems + */ + ++#include <linux/module.h> + #include <linux/config.h> + #include <linux/init.h> ++#include <linux/kernel.h> + #include <linux/mm.h> + #include <linux/smp_lock.h> + #include <linux/irq.h> +@@ -72,11 +74,15 @@ + + /* Bitmask of currently online CPUs */ + cpumask_t cpu_online_map; ++EXPORT_SYMBOL(cpu_online_map); + + cpumask_t cpu_bootout_map; + cpumask_t cpu_bootin_map; +-cpumask_t cpu_callout_map; + static cpumask_t cpu_callin_map; ++cpumask_t cpu_callout_map; ++EXPORT_SYMBOL(cpu_callout_map); ++cpumask_t cpu_possible_map = CPU_MASK_ALL; ++EXPORT_SYMBOL(cpu_possible_map); + + /* Per CPU bogomips and other parameters */ + struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; +@@ -110,7 +116,6 @@ + + void smp_prepare_boot_cpu(void); + void smp_prepare_cpus(unsigned int); +-static void smp_tune_scheduling(void); + static void init_ipi_lock(void); + static void do_boot_cpu(int); + int __cpu_up(unsigned int); +@@ -177,6 +182,9 @@ + } + for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) + physid_set(phys_id, phys_cpu_present_map); ++#ifndef CONFIG_HOTPLUG_CPU ++ cpu_present_map = cpu_possible_map; ++#endif + + show_mp_info(nr_cpu); + +@@ -186,7 +194,6 @@ + * Setup boot CPU information + */ + smp_store_cpu_info(0); /* Final full version of the data */ +- smp_tune_scheduling(); + + /* + * If SMP should be disabled, then really disable it! +@@ -230,11 +237,6 @@ + Dprintk("Boot done.\n"); + } + +-static void __init smp_tune_scheduling(void) +-{ +- /* Nothing to do. */ +-} +- + /* + * init_ipi_lock : Initialize IPI locks. + */ +@@ -629,4 +631,3 @@ + physid_2_cpu[phys_id] = -1; + cpu_2_physid[cpu_id] = -1; + } +- +diff -Naur linux-2.6.16/arch/m32r/lib/getuser.S linux-2.6.16.16/arch/m32r/lib/getuser.S +--- linux-2.6.16/arch/m32r/lib/getuser.S 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/lib/getuser.S 1970-01-01 02:00:00.000000000 +0200 +@@ -1,88 +0,0 @@ +-/* +- * __get_user functions. +- * +- * (C) Copyright 2001 Hirokazu Takata +- * +- * These functions have a non-standard call interface +- * to make them more efficient, especially as they +- * return an error value in addition to the "real" +- * return value. +- */ +- +-#include <linux/config.h> +- +-/* +- * __get_user_X +- * +- * Inputs: r0 contains the address +- * +- * Outputs: r0 is error code (0 or -EFAULT) +- * r1 contains zero-extended value +- * +- * These functions should not modify any other registers, +- * as they get called from within inline assembly. +- */ +- +-#ifdef CONFIG_ISA_DUAL_ISSUE +- +- .text +- .balign 4 +- .globl __get_user_1 +-__get_user_1: +-1: ldub r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_2 +-__get_user_2: +-2: lduh r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_4 +-__get_user_4: +-3: ld r1, @r0 || ldi r0, #0 +- jmp r14 +- +-bad_get_user: +- ldi r1, #0 || ldi r0, #-14 +- jmp r14 +- +-#else /* not CONFIG_ISA_DUAL_ISSUE */ +- +- .text +- .balign 4 +- .globl __get_user_1 +-__get_user_1: +-1: ldub r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_2 +-__get_user_2: +-2: lduh r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __get_user_4 +-__get_user_4: +-3: ld r1, @r0 +- ldi r0, #0 +- jmp r14 +- +-bad_get_user: +- ldi r1, #0 +- ldi r0, #-14 +- jmp r14 +- +-#endif /* not CONFIG_ISA_DUAL_ISSUE */ +- +-.section __ex_table,"a" +- .long 1b,bad_get_user +- .long 2b,bad_get_user +- .long 3b,bad_get_user +-.previous +- +- .end +diff -Naur linux-2.6.16/arch/m32r/lib/Makefile linux-2.6.16.16/arch/m32r/lib/Makefile +--- linux-2.6.16/arch/m32r/lib/Makefile 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/lib/Makefile 2006-05-11 04:56:24.000000000 +0300 +@@ -2,6 +2,6 @@ + # Makefile for M32R-specific library files.. + # + +-lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ +- putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o ++lib-y := checksum.o ashxdi3.o memset.o memcpy.o \ ++ delay.o strlen.o usercopy.o csum_partial_copy.o + +diff -Naur linux-2.6.16/arch/m32r/lib/putuser.S linux-2.6.16.16/arch/m32r/lib/putuser.S +--- linux-2.6.16/arch/m32r/lib/putuser.S 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/m32r/lib/putuser.S 1970-01-01 02:00:00.000000000 +0200 +@@ -1,84 +0,0 @@ +-/* +- * __put_user functions. +- * +- * (C) Copyright 1998 Linus Torvalds +- * (C) Copyright 2001 Hirokazu Takata +- * +- * These functions have a non-standard call interface +- * to make them more efficient. +- */ +- +-#include <linux/config.h> +- +-/* +- * __put_user_X +- * +- * Inputs: r0 contains the address +- * r1 contains the value +- * +- * Outputs: r0 is error code (0 or -EFAULT) +- * r1 is corrupted (will contain "current_task"). +- * +- * These functions should not modify any other registers, +- * as they get called from within inline assembly. +- */ +- +-#ifdef CONFIG_ISA_DUAL_ISSUE +- +- .text +- .balign 4 +- .globl __put_user_1 +-__put_user_1: +-1: stb r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_2 +-__put_user_2: +-2: sth r1, @r0 || ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_4 +-__put_user_4: +-3: st r1, @r0 || ldi r0, #0 +- jmp r14 +- +-bad_put_user: +- ldi r0, #-14 || jmp r14 +- +-#else /* not CONFIG_ISA_DUAL_ISSUE */ +- +- .text +- .balign 4 +- .globl __put_user_1 +-__put_user_1: +-1: stb r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_2 +-__put_user_2: +-2: sth r1, @r0 +- ldi r0, #0 +- jmp r14 +- +- .balign 4 +- .globl __put_user_4 +-__put_user_4: +-3: st r1, @r0 +- ldi r0, #0 +- jmp r14 +- +-bad_put_user: +- ldi r0, #-14 +- jmp r14 +- +-#endif /* not CONFIG_ISA_DUAL_ISSUE */ +- +-.section __ex_table,"a" +- .long 1b,bad_put_user +- .long 2b,bad_put_user +- .long 3b,bad_put_user +-.previous +diff -Naur linux-2.6.16/arch/mips/kernel/branch.c linux-2.6.16.16/arch/mips/kernel/branch.c +--- linux-2.6.16/arch/mips/kernel/branch.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/mips/kernel/branch.c 2006-05-11 04:56:24.000000000 +0300 +@@ -184,7 +184,7 @@ + bit = (insn.i_format.rt >> 2); + bit += (bit != 0); + bit += 23; +- switch (insn.i_format.rt) { ++ switch (insn.i_format.rt & 3) { + case 0: /* bc1f */ + case 2: /* bc1fl */ + if (~fcr31 & (1 << bit)) +diff -Naur linux-2.6.16/arch/mips/mm/c-r4k.c linux-2.6.16.16/arch/mips/mm/c-r4k.c +--- linux-2.6.16/arch/mips/mm/c-r4k.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/mips/mm/c-r4k.c 2006-05-11 04:56:24.000000000 +0300 +@@ -154,7 +154,8 @@ + + static inline void tx49_blast_icache32_page_indexed(unsigned long page) + { +- unsigned long start = page; ++ unsigned long indexmask = current_cpu_data.icache.waysize - 1; ++ unsigned long start = INDEX_BASE + (page & indexmask); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << +diff -Naur linux-2.6.16/arch/powerpc/kernel/pci_64.c linux-2.6.16.16/arch/powerpc/kernel/pci_64.c +--- linux-2.6.16/arch/powerpc/kernel/pci_64.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/powerpc/kernel/pci_64.c 2006-05-11 04:56:24.000000000 +0300 +@@ -78,6 +78,7 @@ + + /* Cached ISA bridge dev. */ + struct pci_dev *ppc64_isabridge_dev = NULL; ++EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); + + static void fixup_broken_pcnet32(struct pci_dev* dev) + { +diff -Naur linux-2.6.16/arch/powerpc/kernel/setup_64.c linux-2.6.16.16/arch/powerpc/kernel/setup_64.c +--- linux-2.6.16/arch/powerpc/kernel/setup_64.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/powerpc/kernel/setup_64.c 2006-05-11 04:56:24.000000000 +0300 +@@ -256,12 +256,10 @@ + /* + * Initialize stab / SLB management except on iSeries + */ +- if (!firmware_has_feature(FW_FEATURE_ISERIES)) { +- if (cpu_has_feature(CPU_FTR_SLB)) +- slb_initialize(); +- else +- stab_initialize(lpaca->stab_real); +- } ++ if (cpu_has_feature(CPU_FTR_SLB)) ++ slb_initialize(); ++ else if (!firmware_has_feature(FW_FEATURE_ISERIES)) ++ stab_initialize(lpaca->stab_real); + + DBG(" <- early_setup()\n"); + } +diff -Naur linux-2.6.16/arch/powerpc/kernel/signal_64.c linux-2.6.16.16/arch/powerpc/kernel/signal_64.c +--- linux-2.6.16/arch/powerpc/kernel/signal_64.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/powerpc/kernel/signal_64.c 2006-05-11 04:56:24.000000000 +0300 +@@ -213,7 +213,7 @@ + /* Default to using normal stack */ + newsp = regs->gpr[1]; + +- if (ka->sa.sa_flags & SA_ONSTACK) { ++ if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) { + if (! on_sig_stack(regs->gpr[1])) + newsp = (current->sas_ss_sp + current->sas_ss_size); + } +diff -Naur linux-2.6.16/arch/x86_64/ia32/Makefile linux-2.6.16.16/arch/x86_64/ia32/Makefile +--- linux-2.6.16/arch/x86_64/ia32/Makefile 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/x86_64/ia32/Makefile 2006-05-11 04:56:24.000000000 +0300 +@@ -27,5 +27,5 @@ + $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE + $(call if_changed,syscall) + +-AFLAGS_vsyscall-sysenter.o = -m32 +-AFLAGS_vsyscall-syscall.o = -m32 ++AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 ++AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 +diff -Naur linux-2.6.16/arch/x86_64/kernel/entry.S linux-2.6.16.16/arch/x86_64/kernel/entry.S +--- linux-2.6.16/arch/x86_64/kernel/entry.S 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/x86_64/kernel/entry.S 2006-05-11 04:56:24.000000000 +0300 +@@ -180,6 +180,10 @@ + * + * XXX if we had a free scratch register we could save the RSP into the stack frame + * and report it properly in ps. Unfortunately we haven't. ++ * ++ * When user can change the frames always force IRET. That is because ++ * it deals with uncanonical addresses better. SYSRET has trouble ++ * with them due to bugs in both AMD and Intel CPUs. + */ + + ENTRY(system_call) +@@ -254,7 +258,10 @@ + xorl %esi,%esi # oldset -> arg2 + call ptregscall_common + 1: movl $_TIF_NEED_RESCHED,%edi +- jmp sysret_check ++ /* Use IRET because user could have changed frame. This ++ works because ptregscall_common has called FIXUP_TOP_OF_STACK. */ ++ cli ++ jmp int_with_check + + badsys: + movq $-ENOSYS,RAX-ARGOFFSET(%rsp) +@@ -280,7 +287,8 @@ + call syscall_trace_leave + RESTORE_TOP_OF_STACK %rbx + RESTORE_REST +- jmp ret_from_sys_call ++ /* Use IRET because user could have changed frame */ ++ jmp int_ret_from_sys_call + CFI_ENDPROC + + /* +@@ -408,25 +416,9 @@ + CFI_ADJUST_CFA_OFFSET -8 + CFI_REGISTER rip, r11 + SAVE_REST +- movq %r11, %r15 +- CFI_REGISTER rip, r15 + FIXUP_TOP_OF_STACK %r11 + call sys_execve +- GET_THREAD_INFO(%rcx) +- bt $TIF_IA32,threadinfo_flags(%rcx) +- CFI_REMEMBER_STATE +- jc exec_32bit + RESTORE_TOP_OF_STACK %r11 +- movq %r15, %r11 +- CFI_REGISTER rip, r11 +- RESTORE_REST +- pushq %r11 +- CFI_ADJUST_CFA_OFFSET 8 +- CFI_REL_OFFSET rip, 0 +- ret +- +-exec_32bit: +- CFI_RESTORE_STATE + movq %rax,RAX(%rsp) + RESTORE_REST + jmp int_ret_from_sys_call +diff -Naur linux-2.6.16/arch/x86_64/kernel/pci-gart.c linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c +--- linux-2.6.16/arch/x86_64/kernel/pci-gart.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/x86_64/kernel/pci-gart.c 2006-05-11 04:56:24.000000000 +0300 +@@ -114,10 +114,6 @@ + static void free_iommu(unsigned long offset, int size) + { + unsigned long flags; +- if (size == 1) { +- clear_bit(offset, iommu_gart_bitmap); +- return; +- } + spin_lock_irqsave(&iommu_bitmap_lock, flags); + __clear_bit_string(iommu_gart_bitmap, offset, size); + spin_unlock_irqrestore(&iommu_bitmap_lock, flags); +diff -Naur linux-2.6.16/arch/x86_64/kernel/process.c linux-2.6.16.16/arch/x86_64/kernel/process.c +--- linux-2.6.16/arch/x86_64/kernel/process.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/x86_64/kernel/process.c 2006-05-11 04:56:24.000000000 +0300 +@@ -527,8 +527,6 @@ + int cpu = smp_processor_id(); + struct tss_struct *tss = &per_cpu(init_tss, cpu); + +- unlazy_fpu(prev_p); +- + /* + * Reload esp0, LDT and the page table pointer: + */ +@@ -591,6 +589,12 @@ + prev->userrsp = read_pda(oldrsp); + write_pda(oldrsp, next->userrsp); + write_pda(pcurrent, next_p); ++ ++ /* This must be here to ensure both math_state_restore() and ++ kernel_fpu_begin() work consistently. ++ And the AMD workaround requires it to be after DS reload. */ ++ unlazy_fpu(prev_p); ++ + write_pda(kernelstack, + task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); + +diff -Naur linux-2.6.16/arch/x86_64/kernel/setup.c linux-2.6.16.16/arch/x86_64/kernel/setup.c +--- linux-2.6.16/arch/x86_64/kernel/setup.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/arch/x86_64/kernel/setup.c 2006-05-11 04:56:24.000000000 +0300 +@@ -909,6 +909,10 @@ + if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) + set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); + ++ /* Enable workaround for FXSAVE leak */ ++ if (c->x86 >= 6) ++ set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); ++ + r = get_model_name(c); + if (!r) { + switch (c->x86) { +diff -Naur linux-2.6.16/block/genhd.c linux-2.6.16.16/block/genhd.c +--- linux-2.6.16/block/genhd.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/block/genhd.c 2006-05-11 04:56:24.000000000 +0300 +@@ -16,8 +16,6 @@ + #include <linux/kobj_map.h> + #include <linux/buffer_head.h> + +-#define MAX_PROBE_HASH 255 /* random */ +- + static struct subsystem block_subsys; + + static DECLARE_MUTEX(block_subsys_sem); +@@ -30,108 +28,29 @@ + struct blk_major_name *next; + int major; + char name[16]; +-} *major_names[MAX_PROBE_HASH]; ++} *major_names[BLKDEV_MAJOR_HASH_SIZE]; + + /* index in the above - for now: assume no multimajor ranges */ + static inline int major_to_index(int major) + { +- return major % MAX_PROBE_HASH; +-} +- +-struct blkdev_info { +- int index; +- struct blk_major_name *bd; +-}; +- +-/* +- * iterate over a list of blkdev_info structures. allows +- * the major_names array to be iterated over from outside this file +- * must be called with the block_subsys_sem held +- */ +-void *get_next_blkdev(void *dev) +-{ +- struct blkdev_info *info; +- +- if (dev == NULL) { +- info = kmalloc(sizeof(*info), GFP_KERNEL); +- if (!info) +- goto out; +- info->index=0; +- info->bd = major_names[info->index]; +- if (info->bd) +- goto out; +- } else { +- info = dev; +- } +- +- while (info->index < ARRAY_SIZE(major_names)) { +- if (info->bd) +- info->bd = info->bd->next; +- if (info->bd) +- goto out; +- /* +- * No devices on this chain, move to the next +- */ +- info->index++; +- info->bd = (info->index < ARRAY_SIZE(major_names)) ? +- major_names[info->index] : NULL; +- if (info->bd) +- goto out; +- } +- +-out: +- return info; +-} +- +-void *acquire_blkdev_list(void) +-{ +- down(&block_subsys_sem); +- return get_next_blkdev(NULL); +-} +- +-void release_blkdev_list(void *dev) +-{ +- up(&block_subsys_sem); +- kfree(dev); ++ return major % BLKDEV_MAJOR_HASH_SIZE; + } + ++#ifdef CONFIG_PROC_FS + +-/* +- * Count the number of records in the blkdev_list. +- * must be called with the block_subsys_sem held +- */ +-int count_blkdev_list(void) ++void blkdev_show(struct seq_file *f, off_t offset) + { +- struct blk_major_name *n; +- int i, count; +- +- count = 0; ++ struct blk_major_name *dp; + +- for (i = 0; i < ARRAY_SIZE(major_names); i++) { +- for (n = major_names[i]; n; n = n->next) +- count++; ++ if (offset < BLKDEV_MAJOR_HASH_SIZE) { ++ down(&block_subsys_sem); ++ for (dp = major_names[offset]; dp; dp = dp->next) ++ seq_printf(f, "%3d %s\n", dp->major, dp->name); ++ up(&block_subsys_sem); + } +- +- return count; +-} +- +-/* +- * extract the major and name values from a blkdev_info struct +- * passed in as a void to *dev. Must be called with +- * block_subsys_sem held +- */ +-int get_blkdev_info(void *dev, int *major, char **name) +-{ +- struct blkdev_info *info = dev; +- +- if (info->bd == NULL) +- return 1; +- +- *major = info->bd->major; +- *name = info->bd->name; +- return 0; + } + ++#endif /* CONFIG_PROC_FS */ + + int register_blkdev(unsigned int major, const char *name) + { +diff -Naur linux-2.6.16/Documentation/dvb/get_dvb_firmware linux-2.6.16.16/Documentation/dvb/get_dvb_firmware +--- linux-2.6.16/Documentation/dvb/get_dvb_firmware 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/Documentation/dvb/get_dvb_firmware 2006-05-11 04:56:24.000000000 +0300 +@@ -240,9 +240,9 @@ + } + + sub nxt2002 { +- my $sourcefile = "Broadband4PC_4_2_11.zip"; ++ my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip"; + my $url = "http://www.bbti.us/download/windows/$sourcefile"; +- my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a"; ++ my $hash = "476befae8c7c1bb9648954060b1eec1f"; + my $outfile = "dvb-fe-nxt2002.fw"; + my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); + +@@ -250,8 +250,8 @@ + + wgetfile($sourcefile, $url); + unzip($sourcefile, $tmpdir); +- verify("$tmpdir/SkyNETU.sys", $hash); +- extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile); ++ verify("$tmpdir/SkyNET.sys", $hash); ++ extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile); + + $outfile; + } +diff -Naur linux-2.6.16/drivers/base/cpu.c linux-2.6.16.16/drivers/base/cpu.c +--- linux-2.6.16/drivers/base/cpu.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/base/cpu.c 2006-05-11 04:56:24.000000000 +0300 +@@ -141,7 +141,7 @@ + return error; + } + +-struct sys_device *get_cpu_sysdev(int cpu) ++struct sys_device *get_cpu_sysdev(unsigned cpu) + { + if (cpu < NR_CPUS) + return cpu_sys_devices[cpu]; +diff -Naur linux-2.6.16/drivers/base/firmware_class.c linux-2.6.16.16/drivers/base/firmware_class.c +--- linux-2.6.16/drivers/base/firmware_class.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/base/firmware_class.c 2006-05-11 04:56:24.000000000 +0300 +@@ -211,18 +211,20 @@ + fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) + { + u8 *new_data; ++ int new_size = fw_priv->alloc_size; + + if (min_size <= fw_priv->alloc_size) + return 0; + +- new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE); ++ new_size = ALIGN(min_size, PAGE_SIZE); ++ new_data = vmalloc(new_size); + if (!new_data) { + printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); + /* Make sure that we don't keep incomplete data */ + fw_load_abort(fw_priv); + return -ENOMEM; + } +- fw_priv->alloc_size += PAGE_SIZE; ++ fw_priv->alloc_size = new_size; + if (fw_priv->fw->data) { + memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); + vfree(fw_priv->fw->data); +diff -Naur linux-2.6.16/drivers/base/node.c linux-2.6.16.16/drivers/base/node.c +--- linux-2.6.16/drivers/base/node.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/base/node.c 2006-05-11 04:56:24.000000000 +0300 +@@ -106,7 +106,7 @@ + other_node = 0; + for (i = 0; i < MAX_NR_ZONES; i++) { + struct zone *z = &pg->node_zones[i]; +- for (cpu = 0; cpu < NR_CPUS; cpu++) { ++ for_each_online_cpu(cpu) { + struct per_cpu_pageset *ps = zone_pcp(z,cpu); + numa_hit += ps->numa_hit; + numa_miss += ps->numa_miss; +diff -Naur linux-2.6.16/drivers/block/cciss.c linux-2.6.16.16/drivers/block/cciss.c +--- linux-2.6.16/drivers/block/cciss.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/block/cciss.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1181,6 +1181,53 @@ + return 0; + } + ++static inline void complete_buffers(struct bio *bio, int status) ++{ ++ while (bio) { ++ struct bio *xbh = bio->bi_next; ++ int nr_sectors = bio_sectors(bio); ++ ++ bio->bi_next = NULL; ++ blk_finished_io(len); ++ bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); ++ bio = xbh; ++ } ++ ++} ++ ++static void cciss_softirq_done(struct request *rq) ++{ ++ CommandList_struct *cmd = rq->completion_data; ++ ctlr_info_t *h = hba[cmd->ctlr]; ++ unsigned long flags; ++ u64bit temp64; ++ int i, ddir; ++ ++ if (cmd->Request.Type.Direction == XFER_READ) ++ ddir = PCI_DMA_FROMDEVICE; ++ else ++ ddir = PCI_DMA_TODEVICE; ++ ++ /* command did not need to be retried */ ++ /* unmap the DMA mapping for all the scatter gather elements */ ++ for(i=0; i<cmd->Header.SGList; i++) { ++ temp64.val32.lower = cmd->SG[i].Addr.lower; ++ temp64.val32.upper = cmd->SG[i].Addr.upper; ++ pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); ++ } ++ ++ complete_buffers(rq->bio, rq->errors); ++ ++#ifdef CCISS_DEBUG ++ printk("Done with %p\n", rq); ++#endif /* CCISS_DEBUG */ ++ ++ spin_lock_irqsave(&h->lock, flags); ++ end_that_request_last(rq, rq->errors); ++ cmd_free(h, cmd,1); ++ spin_unlock_irqrestore(&h->lock, flags); ++} ++ + /* This function will check the usage_count of the drive to be updated/added. + * If the usage_count is zero then the drive information will be updated and + * the disk will be re-registered with the kernel. If not then it will be +@@ -1249,6 +1296,8 @@ + + blk_queue_max_sectors(disk->queue, 512); + ++ blk_queue_softirq_done(disk->queue, cciss_softirq_done); ++ + disk->queue->queuedata = hba[ctlr]; + + blk_queue_hardsect_size(disk->queue, +@@ -2148,20 +2197,6 @@ + addQ (&(h->cmpQ), c); + } + } +- +-static inline void complete_buffers(struct bio *bio, int status) +-{ +- while (bio) { +- struct bio *xbh = bio->bi_next; +- int nr_sectors = bio_sectors(bio); +- +- bio->bi_next = NULL; +- blk_finished_io(len); +- bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); +- bio = xbh; +- } +- +-} + /* Assumes that CCISS_LOCK(h->ctlr) is held. */ + /* Zeros out the error record and then resends the command back */ + /* to the controller */ +@@ -2179,39 +2214,6 @@ + start_io(h); + } + +-static void cciss_softirq_done(struct request *rq) +-{ +- CommandList_struct *cmd = rq->completion_data; +- ctlr_info_t *h = hba[cmd->ctlr]; +- unsigned long flags; +- u64bit temp64; +- int i, ddir; +- +- if (cmd->Request.Type.Direction == XFER_READ) +- ddir = PCI_DMA_FROMDEVICE; +- else +- ddir = PCI_DMA_TODEVICE; +- +- /* command did not need to be retried */ +- /* unmap the DMA mapping for all the scatter gather elements */ +- for(i=0; i<cmd->Header.SGList; i++) { +- temp64.val32.lower = cmd->SG[i].Addr.lower; +- temp64.val32.upper = cmd->SG[i].Addr.upper; +- pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); +- } +- +- complete_buffers(rq->bio, rq->errors); +- +-#ifdef CCISS_DEBUG +- printk("Done with %p\n", rq); +-#endif /* CCISS_DEBUG */ +- +- spin_lock_irqsave(&h->lock, flags); +- end_that_request_last(rq, rq->errors); +- cmd_free(h, cmd,1); +- spin_unlock_irqrestore(&h->lock, flags); +-} +- + /* checks the status of the job and calls complete buffers to mark all + * buffers for the completed job. Note that this function does not need + * to hold the hba/queue lock. +@@ -3269,8 +3271,8 @@ + unregister_blkdev(hba[i]->major, hba[i]->devname); + clean1: + release_io_mem(hba[i]); +- free_hba(i); + hba[i]->busy_initializing = 0; ++ free_hba(i); + return(-1); + } + +diff -Naur linux-2.6.16/drivers/char/agp/efficeon-agp.c linux-2.6.16.16/drivers/char/agp/efficeon-agp.c +--- linux-2.6.16/drivers/char/agp/efficeon-agp.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/agp/efficeon-agp.c 2006-05-11 04:56:24.000000000 +0300 +@@ -64,6 +64,12 @@ + {.mask = 0x00000001, .type = 0} + }; + ++/* This function does the same thing as mask_memory() for this chipset... */ ++static inline unsigned long efficeon_mask_memory(unsigned long addr) ++{ ++ return addr | 0x00000001; ++} ++ + static struct aper_size_info_lvl2 efficeon_generic_sizes[4] = + { + {256, 65536, 0}, +@@ -251,7 +257,7 @@ + last_page = NULL; + for (i = 0; i < count; i++) { + int index = pg_start + i; +- unsigned long insert = mem->memory[i]; ++ unsigned long insert = efficeon_mask_memory(mem->memory[i]); + + page = (unsigned int *) efficeon_private.l1_table[index >> 10]; + +diff -Naur linux-2.6.16/drivers/char/cs5535_gpio.c linux-2.6.16.16/drivers/char/cs5535_gpio.c +--- linux-2.6.16/drivers/char/cs5535_gpio.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/cs5535_gpio.c 2006-05-11 04:56:24.000000000 +0300 +@@ -241,9 +241,10 @@ + static void __exit cs5535_gpio_cleanup(void) + { + dev_t dev_id = MKDEV(major, 0); ++ ++ cdev_del(&cs5535_gpio_cdev); + unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); +- if (gpio_base != 0) +- release_region(gpio_base, CS5535_GPIO_SIZE); ++ release_region(gpio_base, CS5535_GPIO_SIZE); + } + + module_init(cs5535_gpio_init); +diff -Naur linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c +--- linux-2.6.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/ipmi/ipmi_bt_sm.c 2006-05-11 04:56:24.000000000 +0300 +@@ -165,7 +165,7 @@ + { + unsigned int i; + +- if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) ++ if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) + return -1; + + if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) +diff -Naur linux-2.6.16/drivers/char/Kconfig linux-2.6.16.16/drivers/char/Kconfig +--- linux-2.6.16/drivers/char/Kconfig 2006-05-18 01:12:22.000000000 +0300 ++++ linux-2.6.16.16/drivers/char/Kconfig 2006-05-17 21:41:29.000000000 +0300 +@@ -187,6 +187,7 @@ + config ISI + tristate "Multi-Tech multiport card support (EXPERIMENTAL)" + depends on SERIAL_NONSTANDARD ++ select FW_LOADER + help + This is a driver for the Multi-Tech cards which provide several + serial ports. The driver is experimental and can currently only be +diff -Naur linux-2.6.16/drivers/char/snsc.c linux-2.6.16.16/drivers/char/snsc.c +--- linux-2.6.16/drivers/char/snsc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/snsc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -391,7 +391,8 @@ + format_module_id(devnamep, geo_module(geoid), + MODULE_FORMAT_BRIEF); + devnamep = devname + strlen(devname); +- sprintf(devnamep, "#%d", geo_slab(geoid)); ++ sprintf(devnamep, "^%d#%d", geo_slot(geoid), ++ geo_slab(geoid)); + + /* allocate sysctl device data */ + scd = kmalloc(sizeof (struct sysctl_data_s), +diff -Naur linux-2.6.16/drivers/char/sonypi.c linux-2.6.16.16/drivers/char/sonypi.c +--- linux-2.6.16/drivers/char/sonypi.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/sonypi.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1341,6 +1341,9 @@ + else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; ++ else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, ++ PCI_DEVICE_ID_INTEL_ICH7_1, NULL))) ++ sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; + else + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; + +diff -Naur linux-2.6.16/drivers/char/tipar.c linux-2.6.16.16/drivers/char/tipar.c +--- linux-2.6.16/drivers/char/tipar.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/tipar.c 2006-05-11 04:56:24.000000000 +0300 +@@ -515,7 +515,7 @@ + err = PTR_ERR(tipar_class); + goto out_chrdev; + } +- if (parport_register_driver(&tipar_driver) || tp_count == 0) { ++ if (parport_register_driver(&tipar_driver)) { + printk(KERN_ERR "tipar: unable to register with parport\n"); + err = -EIO; + goto out_class; +diff -Naur linux-2.6.16/drivers/char/tlclk.c linux-2.6.16.16/drivers/char/tlclk.c +--- linux-2.6.16/drivers/char/tlclk.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/tlclk.c 2006-05-11 04:56:24.000000000 +0300 +@@ -327,7 +327,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(received_ref_clk3a, S_IWUGO, NULL, ++static DEVICE_ATTR(received_ref_clk3a, (S_IWUSR|S_IWGRP), NULL, + store_received_ref_clk3a); + + +@@ -349,7 +349,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(received_ref_clk3b, S_IWUGO, NULL, ++static DEVICE_ATTR(received_ref_clk3b, (S_IWUSR|S_IWGRP), NULL, + store_received_ref_clk3b); + + +@@ -371,7 +371,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clk3b_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clk3b_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clk3b_output); + + static ssize_t store_enable_clk3a_output(struct device *d, +@@ -392,7 +392,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clk3a_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clk3a_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clk3a_output); + + static ssize_t store_enable_clkb1_output(struct device *d, +@@ -413,7 +413,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clkb1_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clkb1_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clkb1_output); + + +@@ -435,7 +435,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clka1_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clka1_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clka1_output); + + static ssize_t store_enable_clkb0_output(struct device *d, +@@ -456,7 +456,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clkb0_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clkb0_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clkb0_output); + + static ssize_t store_enable_clka0_output(struct device *d, +@@ -477,7 +477,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(enable_clka0_output, S_IWUGO, NULL, ++static DEVICE_ATTR(enable_clka0_output, (S_IWUSR|S_IWGRP), NULL, + store_enable_clka0_output); + + static ssize_t store_select_amcb2_transmit_clock(struct device *d, +@@ -519,7 +519,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_amcb2_transmit_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_amcb2_transmit_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_amcb2_transmit_clock); + + static ssize_t store_select_amcb1_transmit_clock(struct device *d, +@@ -560,7 +560,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_amcb1_transmit_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_amcb1_transmit_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_amcb1_transmit_clock); + + static ssize_t store_select_redundant_clock(struct device *d, +@@ -581,7 +581,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_redundant_clock, S_IWUGO, NULL, ++static DEVICE_ATTR(select_redundant_clock, (S_IWUSR|S_IWGRP), NULL, + store_select_redundant_clock); + + static ssize_t store_select_ref_frequency(struct device *d, +@@ -602,7 +602,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(select_ref_frequency, S_IWUGO, NULL, ++static DEVICE_ATTR(select_ref_frequency, (S_IWUSR|S_IWGRP), NULL, + store_select_ref_frequency); + + static ssize_t store_filter_select(struct device *d, +@@ -623,7 +623,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(filter_select, S_IWUGO, NULL, store_filter_select); ++static DEVICE_ATTR(filter_select, (S_IWUSR|S_IWGRP), NULL, store_filter_select); + + static ssize_t store_hardware_switching_mode(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -643,7 +643,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(hardware_switching_mode, S_IWUGO, NULL, ++static DEVICE_ATTR(hardware_switching_mode, (S_IWUSR|S_IWGRP), NULL, + store_hardware_switching_mode); + + static ssize_t store_hardware_switching(struct device *d, +@@ -664,7 +664,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(hardware_switching, S_IWUGO, NULL, ++static DEVICE_ATTR(hardware_switching, (S_IWUSR|S_IWGRP), NULL, + store_hardware_switching); + + static ssize_t store_refalign (struct device *d, +@@ -684,7 +684,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(refalign, S_IWUGO, NULL, store_refalign); ++static DEVICE_ATTR(refalign, (S_IWUSR|S_IWGRP), NULL, store_refalign); + + static ssize_t store_mode_select (struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -704,7 +704,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(mode_select, S_IWUGO, NULL, store_mode_select); ++static DEVICE_ATTR(mode_select, (S_IWUSR|S_IWGRP), NULL, store_mode_select); + + static ssize_t store_reset (struct device *d, + struct device_attribute *attr, const char *buf, size_t count) +@@ -724,7 +724,7 @@ + return strnlen(buf, count); + } + +-static DEVICE_ATTR(reset, S_IWUGO, NULL, store_reset); ++static DEVICE_ATTR(reset, (S_IWUSR|S_IWGRP), NULL, store_reset); + + static struct attribute *tlclk_sysfs_entries[] = { + &dev_attr_current_ref.attr, +@@ -767,6 +767,7 @@ + printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); + return ret; + } ++ tlclk_major = ret; + alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); + if (!alarm_events) + goto out1; +diff -Naur linux-2.6.16/drivers/char/tty_io.c linux-2.6.16.16/drivers/char/tty_io.c +--- linux-2.6.16/drivers/char/tty_io.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/char/tty_io.c 2006-05-11 04:56:24.000000000 +0300 +@@ -2706,7 +2706,11 @@ + } + task_lock(p); + if (p->files) { +- rcu_read_lock(); ++ /* ++ * We don't take a ref to the file, so we must ++ * hold ->file_lock instead. ++ */ ++ spin_lock(&p->files->file_lock); + fdt = files_fdtable(p->files); + for (i=0; i < fdt->max_fds; i++) { + filp = fcheck_files(p->files, i); +@@ -2721,7 +2725,7 @@ + break; + } + } +- rcu_read_unlock(); ++ spin_unlock(&p->files->file_lock); + } + task_unlock(p); + } while_each_task_pid(session, PIDTYPE_SID, p); +diff -Naur linux-2.6.16/drivers/edac/Kconfig linux-2.6.16.16/drivers/edac/Kconfig +--- linux-2.6.16/drivers/edac/Kconfig 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/edac/Kconfig 2006-05-11 04:56:24.000000000 +0300 +@@ -71,7 +71,7 @@ + + config EDAC_E752X + tristate "Intel e752x (e7520, e7525, e7320)" +- depends on EDAC_MM_EDAC && PCI ++ depends on EDAC_MM_EDAC && PCI && HOTPLUG + help + Support for error detection and correction on the Intel + E7520, E7525, E7320 server chipsets. +diff -Naur linux-2.6.16/drivers/i2c/busses/i2c-i801.c linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c +--- linux-2.6.16/drivers/i2c/busses/i2c-i801.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/i2c/busses/i2c-i801.c 2006-05-11 04:56:24.000000000 +0300 +@@ -478,6 +478,11 @@ + ret = i801_transaction(); + } + ++ /* Some BIOSes don't like it when PEC is enabled at reboot or resume ++ time, so we forcibly disable it after every transaction. */ ++ if (hwpec) ++ outb_p(0, SMBAUXCTL); ++ + if(block) + return ret; + if(ret) +diff -Naur linux-2.6.16/drivers/i2c/chips/m41t00.c linux-2.6.16.16/drivers/i2c/chips/m41t00.c +--- linux-2.6.16/drivers/i2c/chips/m41t00.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/i2c/chips/m41t00.c 2006-05-11 04:56:24.000000000 +0300 +@@ -129,13 +129,13 @@ + if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) + || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) + < 0) +- || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f) ++ || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) + < 0)) + + dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); +diff -Naur linux-2.6.16/drivers/ide/pci/alim15x3.c linux-2.6.16.16/drivers/ide/pci/alim15x3.c +--- linux-2.6.16/drivers/ide/pci/alim15x3.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/ide/pci/alim15x3.c 2006-05-11 04:56:24.000000000 +0300 +@@ -731,6 +731,8 @@ + + if(m5229_revision <= 0x20) + tmpbyte = (tmpbyte & (~0x02)) | 0x01; ++ else if (m5229_revision == 0xc7) ++ tmpbyte |= 0x03; + else + tmpbyte |= 0x01; + +diff -Naur linux-2.6.16/drivers/ieee1394/sbp2.c linux-2.6.16.16/drivers/ieee1394/sbp2.c +--- linux-2.6.16/drivers/ieee1394/sbp2.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/ieee1394/sbp2.c 2006-05-11 04:56:24.000000000 +0300 +@@ -495,22 +495,17 @@ + /* + * This function finds the sbp2_command for a given outstanding SCpnt. + * Only looks at the inuse list. ++ * Must be called with scsi_id->sbp2_command_orb_lock held. + */ +-static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt) ++static struct sbp2_command_info *sbp2util_find_command_for_SCpnt( ++ struct scsi_id_instance_data *scsi_id, void *SCpnt) + { + struct sbp2_command_info *command; +- unsigned long flags; + +- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); +- if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) { +- list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) { +- if (command->Current_SCpnt == SCpnt) { +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); ++ if (!list_empty(&scsi_id->sbp2_command_orb_inuse)) ++ list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) ++ if (command->Current_SCpnt == SCpnt) + return command; +- } +- } +- } +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + return NULL; + } + +@@ -579,17 +574,15 @@ + + /* + * This function moves a command to the completed orb list. ++ * Must be called with scsi_id->sbp2_command_orb_lock held. + */ +-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, +- struct sbp2_command_info *command) ++static void sbp2util_mark_command_completed( ++ struct scsi_id_instance_data *scsi_id, ++ struct sbp2_command_info *command) + { +- unsigned long flags; +- +- spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + list_del(&command->list); + sbp2util_free_command_dma(command); + list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed); +- spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + } + + /* +@@ -2177,7 +2170,9 @@ + * Matched status with command, now grab scsi command pointers and check status + */ + SCpnt = command->Current_SCpnt; ++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + sbp2util_mark_command_completed(scsi_id, command); ++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + + if (SCpnt) { + +@@ -2513,6 +2508,7 @@ + (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; + struct sbp2scsi_host_info *hi = scsi_id->hi; + struct sbp2_command_info *command; ++ unsigned long flags; + + SBP2_ERR("aborting sbp2 command"); + scsi_print_command(SCpnt); +@@ -2523,6 +2519,7 @@ + * Right now, just return any matching command structures + * to the free pool. + */ ++ spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); + command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt); + if (command) { + SBP2_DEBUG("Found command to abort"); +@@ -2540,6 +2537,7 @@ + command->Current_done(command->Current_SCpnt); + } + } ++ spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + + /* + * Initiate a fetch agent reset. +diff -Naur linux-2.6.16/drivers/macintosh/therm_adt746x.c linux-2.6.16.16/drivers/macintosh/therm_adt746x.c +--- linux-2.6.16/drivers/macintosh/therm_adt746x.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/macintosh/therm_adt746x.c 2006-05-11 04:56:24.000000000 +0300 +@@ -627,8 +627,8 @@ + if(therm_type == ADT7460) + device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); + +-#ifndef CONFIG_I2C_KEYWEST +- request_module("i2c-keywest"); ++#ifndef CONFIG_I2C_POWERMAC ++ request_module("i2c-powermac"); + #endif + + return i2c_add_driver(&thermostat_driver); +diff -Naur linux-2.6.16/drivers/md/dm.c linux-2.6.16.16/drivers/md/dm.c +--- linux-2.6.16/drivers/md/dm.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/md/dm.c 2006-05-11 04:56:24.000000000 +0300 +@@ -533,30 +533,35 @@ + + } else { + /* +- * Create two copy bios to deal with io that has +- * been split across a target. ++ * Handle a bvec that must be split between two or more targets. + */ + struct bio_vec *bv = bio->bi_io_vec + ci->idx; ++ sector_t remaining = to_sector(bv->bv_len); ++ unsigned int offset = 0; + +- clone = split_bvec(bio, ci->sector, ci->idx, +- bv->bv_offset, max); +- __map_bio(ti, clone, tio); +- +- ci->sector += max; +- ci->sector_count -= max; +- ti = dm_table_find_target(ci->map, ci->sector); +- +- len = to_sector(bv->bv_len) - max; +- clone = split_bvec(bio, ci->sector, ci->idx, +- bv->bv_offset + to_bytes(max), len); +- tio = alloc_tio(ci->md); +- tio->io = ci->io; +- tio->ti = ti; +- memset(&tio->info, 0, sizeof(tio->info)); +- __map_bio(ti, clone, tio); ++ do { ++ if (offset) { ++ ti = dm_table_find_target(ci->map, ci->sector); ++ max = max_io_len(ci->md, ci->sector, ti); ++ ++ tio = alloc_tio(ci->md); ++ tio->io = ci->io; ++ tio->ti = ti; ++ memset(&tio->info, 0, sizeof(tio->info)); ++ } ++ ++ len = min(remaining, max); ++ ++ clone = split_bvec(bio, ci->sector, ci->idx, ++ bv->bv_offset + offset, len); ++ ++ __map_bio(ti, clone, tio); ++ ++ ci->sector += len; ++ ci->sector_count -= len; ++ offset += to_bytes(len); ++ } while (remaining -= len); + +- ci->sector += len; +- ci->sector_count -= len; + ci->idx++; + } + } +@@ -1093,6 +1098,7 @@ + { + struct dm_table *map = NULL; + DECLARE_WAITQUEUE(wait, current); ++ struct bio *def; + int r = -EINVAL; + + down(&md->suspend_lock); +@@ -1152,9 +1158,11 @@ + /* were we interrupted ? */ + r = -EINTR; + if (atomic_read(&md->pending)) { ++ clear_bit(DMF_BLOCK_IO, &md->flags); ++ def = bio_list_get(&md->deferred); ++ __flush_deferred_io(md, def); + up_write(&md->io_lock); + unlock_fs(md); +- clear_bit(DMF_BLOCK_IO, &md->flags); + goto out; + } + up_write(&md->io_lock); +diff -Naur linux-2.6.16/drivers/md/dm-snap.c linux-2.6.16.16/drivers/md/dm-snap.c +--- linux-2.6.16/drivers/md/dm-snap.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/md/dm-snap.c 2006-05-11 04:56:24.000000000 +0300 +@@ -542,8 +542,12 @@ + { + struct dm_snapshot *s = (struct dm_snapshot *) ti->private; + ++ /* Prevent further origin writes from using this snapshot. */ ++ /* After this returns there can be no new kcopyd jobs. */ + unregister_snapshot(s); + ++ kcopyd_client_destroy(s->kcopyd_client); ++ + exit_exception_table(&s->pending, pending_cache); + exit_exception_table(&s->complete, exception_cache); + +@@ -552,7 +556,7 @@ + + dm_put_device(ti, s->origin); + dm_put_device(ti, s->cow); +- kcopyd_client_destroy(s->kcopyd_client); ++ + kfree(s); + } + +diff -Naur linux-2.6.16/drivers/md/kcopyd.c linux-2.6.16.16/drivers/md/kcopyd.c +--- linux-2.6.16/drivers/md/kcopyd.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/md/kcopyd.c 2006-05-11 04:56:24.000000000 +0300 +@@ -44,6 +44,9 @@ + struct page_list *pages; + unsigned int nr_pages; + unsigned int nr_free_pages; ++ ++ wait_queue_head_t destroyq; ++ atomic_t nr_jobs; + }; + + static struct page_list *alloc_pl(void) +@@ -293,10 +296,15 @@ + int read_err = job->read_err; + unsigned int write_err = job->write_err; + kcopyd_notify_fn fn = job->fn; ++ struct kcopyd_client *kc = job->kc; + +- kcopyd_put_pages(job->kc, job->pages); ++ kcopyd_put_pages(kc, job->pages); + mempool_free(job, _job_pool); + fn(read_err, write_err, context); ++ ++ if (atomic_dec_and_test(&kc->nr_jobs)) ++ wake_up(&kc->destroyq); ++ + return 0; + } + +@@ -431,6 +439,7 @@ + */ + static void dispatch_job(struct kcopyd_job *job) + { ++ atomic_inc(&job->kc->nr_jobs); + push(&_pages_jobs, job); + wake(); + } +@@ -670,6 +679,9 @@ + return r; + } + ++ init_waitqueue_head(&kc->destroyq); ++ atomic_set(&kc->nr_jobs, 0); ++ + client_add(kc); + *result = kc; + return 0; +@@ -677,6 +689,9 @@ + + void kcopyd_client_destroy(struct kcopyd_client *kc) + { ++ /* Wait for completion of all jobs submitted by this client. */ ++ wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs)); ++ + dm_io_put(kc->nr_pages); + client_free_pages(kc); + client_del(kc); +diff -Naur linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c +--- linux-2.6.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/media/dvb/dvb-usb/cxusb.c 2006-05-11 04:56:24.000000000 +0300 +@@ -149,6 +149,15 @@ + return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); + } + ++static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) ++{ ++ u8 b = 0; ++ if (onoff) ++ return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); ++ else ++ return 0; ++} ++ + static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) + { + u8 buf[2] = { 0x03, 0x00 }; +@@ -505,7 +514,7 @@ + .size_of_priv = sizeof(struct cxusb_state), + + .streaming_ctrl = cxusb_streaming_ctrl, +- .power_ctrl = cxusb_power_ctrl, ++ .power_ctrl = cxusb_bluebird_power_ctrl, + .frontend_attach = cxusb_lgdt3303_frontend_attach, + .tuner_attach = cxusb_lgh064f_tuner_attach, + +@@ -545,7 +554,7 @@ + .size_of_priv = sizeof(struct cxusb_state), + + .streaming_ctrl = cxusb_streaming_ctrl, +- .power_ctrl = cxusb_power_ctrl, ++ .power_ctrl = cxusb_bluebird_power_ctrl, + .frontend_attach = cxusb_dee1601_frontend_attach, + .tuner_attach = cxusb_dee1601_tuner_attach, + +@@ -594,7 +603,7 @@ + .size_of_priv = sizeof(struct cxusb_state), + + .streaming_ctrl = cxusb_streaming_ctrl, +- .power_ctrl = cxusb_power_ctrl, ++ .power_ctrl = cxusb_bluebird_power_ctrl, + .frontend_attach = cxusb_mt352_frontend_attach, + .tuner_attach = cxusb_lgz201_tuner_attach, + +@@ -634,7 +643,7 @@ + .size_of_priv = sizeof(struct cxusb_state), + + .streaming_ctrl = cxusb_streaming_ctrl, +- .power_ctrl = cxusb_power_ctrl, ++ .power_ctrl = cxusb_bluebird_power_ctrl, + .frontend_attach = cxusb_mt352_frontend_attach, + .tuner_attach = cxusb_dtt7579_tuner_attach, + +diff -Naur linux-2.6.16/drivers/media/video/Kconfig linux-2.6.16.16/drivers/media/video/Kconfig +--- linux-2.6.16/drivers/media/video/Kconfig 2006-05-18 01:12:22.000000000 +0300 ++++ linux-2.6.16.16/drivers/media/video/Kconfig 2006-05-17 21:41:30.000000000 +0300 +@@ -349,6 +349,7 @@ + config VIDEO_DECODER + tristate "Add support for additional video chipsets" + depends on VIDEO_DEV && I2C && EXPERIMENTAL ++ select FW_LOADER + ---help--- + Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 + video decoders. +diff -Naur linux-2.6.16/drivers/media/video/saa7127.c linux-2.6.16.16/drivers/media/video/saa7127.c +--- linux-2.6.16/drivers/media/video/saa7127.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/media/video/saa7127.c 2006-05-11 04:56:24.000000000 +0300 +@@ -141,6 +141,7 @@ + static const struct i2c_reg_value saa7129_init_config_extra[] = { + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, + { SAA7127_REG_VTRIG, 0xfa }, ++ { 0, 0 } + }; + + static const struct i2c_reg_value saa7127_init_config_common[] = { +diff -Naur linux-2.6.16/drivers/media/video/tuner-types.c linux-2.6.16.16/drivers/media/video/tuner-types.c +--- linux-2.6.16/drivers/media/video/tuner-types.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/media/video/tuner-types.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1087,8 +1087,8 @@ + /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ + + static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { +- { 16 * 175.75 /*MHz*/, 0x01, }, +- { 16 * 410.25 /*MHz*/, 0x02, }, ++ { 16 * 130.00 /*MHz*/, 0x01, }, ++ { 16 * 364.50 /*MHz*/, 0x02, }, + { 16 * 999.99 , 0x08, }, + }; + +diff -Naur linux-2.6.16/drivers/mtd/nand/Kconfig linux-2.6.16.16/drivers/mtd/nand/Kconfig +--- linux-2.6.16/drivers/mtd/nand/Kconfig 2006-05-18 01:12:23.000000000 +0300 ++++ linux-2.6.16.16/drivers/mtd/nand/Kconfig 2006-05-17 22:32:57.000000000 +0300 +@@ -184,15 +184,14 @@ + Even if you leave this disabled, you can enable BBT writes at module + load time (assuming you build diskonchip as a module) with the module + parameter "inftl_bbt_write=1". +- +- config MTD_NAND_SHARPSL +- bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" +- depends on MTD_NAND && ARCH_PXA +- +- config MTD_NAND_NANDSIM +- bool "Support for NAND Flash Simulator" +- depends on MTD_NAND && MTD_PARTITIONS + ++config MTD_NAND_SHARPSL ++ tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" ++ depends on MTD_NAND && ARCH_PXA ++ ++config MTD_NAND_NANDSIM ++ tristate "Support for NAND Flash Simulator" ++ depends on MTD_NAND && MTD_PARTITIONS + help + The simulator may simulate verious NAND flash chips for the + MTD nand layer. +@@ -200,7 +199,6 @@ + config MTD_NAND_OMAP_HW + bool "OMAP HW NAND Flash controller support" + depends on ARM && ARCH_OMAP16XX && MTD_NAND +- + help + Driver for TI OMAP16xx hardware NAND flash controller. + +diff -Naur linux-2.6.16/drivers/net/e1000/e1000_main.c linux-2.6.16.16/drivers/net/e1000/e1000_main.c +--- linux-2.6.16/drivers/net/e1000/e1000_main.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/e1000/e1000_main.c 2006-05-11 04:56:24.000000000 +0300 +@@ -3851,6 +3851,7 @@ + skb_shinfo(skb)->nr_frags++; + skb->len += length; + skb->data_len += length; ++ skb->truesize += length; + } + + e1000_rx_checksum(adapter, staterr, +diff -Naur linux-2.6.16/drivers/net/irda/irda-usb.c linux-2.6.16.16/drivers/net/irda/irda-usb.c +--- linux-2.6.16/drivers/net/irda/irda-usb.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/irda/irda-usb.c 2006-05-11 04:56:24.000000000 +0300 +@@ -740,7 +740,7 @@ + struct sk_buff *newskb; + struct sk_buff *dataskb; + struct urb *next_urb; +- int docopy; ++ unsigned int len, docopy; + + IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); + +@@ -851,10 +851,11 @@ + dataskb->dev = self->netdev; + dataskb->mac.raw = dataskb->data; + dataskb->protocol = htons(ETH_P_IRDA); ++ len = dataskb->len; + netif_rx(dataskb); + + /* Keep stats up to date */ +- self->stats.rx_bytes += dataskb->len; ++ self->stats.rx_bytes += len; + self->stats.rx_packets++; + self->netdev->last_rx = jiffies; + +diff -Naur linux-2.6.16/drivers/net/sky2.c linux-2.6.16.16/drivers/net/sky2.c +--- linux-2.6.16/drivers/net/sky2.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/sky2.c 2006-05-11 04:56:24.000000000 +0300 +@@ -579,8 +579,8 @@ + reg = gma_read16(hw, port, GM_PHY_ADDR); + gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); + +- for (i = 0; i < GM_MIB_CNT_SIZE; i++) +- gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i); ++ for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4) ++ gma_read16(hw, port, i); + gma_write16(hw, port, GM_PHY_ADDR, reg); + + /* transmit control */ +diff -Naur linux-2.6.16/drivers/net/sky2.h linux-2.6.16.16/drivers/net/sky2.h +--- linux-2.6.16/drivers/net/sky2.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/sky2.h 2006-05-11 04:56:24.000000000 +0300 +@@ -1380,6 +1380,7 @@ + /* MIB Counters */ + #define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ + #define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ ++#define GM_MIB_CNT_END 0x025C /* Last MIB counter */ + + /* + * MIB Counters base address definitions (low word) - +diff -Naur linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c +--- linux-2.6.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/wireless/hostap/hostap_80211_tx.c 2006-05-11 04:56:24.000000000 +0300 +@@ -469,7 +469,7 @@ + } + + if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && +- !(fc & IEEE80211_FCTL_VERS)) { ++ !(fc & IEEE80211_FCTL_PROTECTED)) { + no_encrypt = 1; + PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " + "unencrypted EAPOL frame\n", dev->name); +diff -Naur linux-2.6.16/drivers/net/wireless/ipw2200.c linux-2.6.16.16/drivers/net/wireless/ipw2200.c +--- linux-2.6.16/drivers/net/wireless/ipw2200.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/wireless/ipw2200.c 2006-05-11 04:56:24.000000000 +0300 +@@ -9956,9 +9956,8 @@ + return -EINVAL; + down(&p->sem); + memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); +- for (i = IPW_EEPROM_DATA; +- i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) +- ipw_write8(p, i, p->eeprom[i]); ++ for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++) ++ ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]); + up(&p->sem); + return 0; + } +diff -Naur linux-2.6.16/drivers/net/wireless/Kconfig linux-2.6.16.16/drivers/net/wireless/Kconfig +--- linux-2.6.16/drivers/net/wireless/Kconfig 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/net/wireless/Kconfig 2006-05-11 04:56:24.000000000 +0300 +@@ -239,7 +239,8 @@ + + config AIRO + tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" +- depends on NET_RADIO && ISA_DMA_API && CRYPTO && (PCI || BROKEN) ++ depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) ++ select CRYPTO + ---help--- + This is the standard Linux driver to support Cisco/Aironet ISA and + PCI 802.11 wireless cards. +@@ -374,6 +375,7 @@ + config PCMCIA_SPECTRUM + tristate "Symbol Spectrum24 Trilogy PCMCIA card support" + depends on NET_RADIO && PCMCIA && HERMES ++ select FW_LOADER + ---help--- + + This is a driver for 802.11b cards using RAM-loadable Symbol +@@ -387,6 +389,7 @@ + config AIRO_CS + tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" + depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) ++ select CRYPTO + ---help--- + This is the standard Linux driver to support Cisco/Aironet PCMCIA + 802.11 wireless cards. This driver is the same as the Aironet +diff -Naur linux-2.6.16/drivers/pcmcia/ds.c linux-2.6.16.16/drivers/pcmcia/ds.c +--- linux-2.6.16/drivers/pcmcia/ds.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/pcmcia/ds.c 2006-05-11 04:56:24.000000000 +0300 +@@ -546,7 +546,7 @@ + tmp = vers1->str + vers1->ofs[i]; + + length = strlen(tmp) + 1; +- if ((length < 3) || (length > 255)) ++ if ((length < 2) || (length > 255)) + continue; + + p_dev->prod_id[i] = kmalloc(sizeof(char) * length, +diff -Naur linux-2.6.16/drivers/scsi/3w-9xxx.c linux-2.6.16.16/drivers/scsi/3w-9xxx.c +--- linux-2.6.16/drivers/scsi/3w-9xxx.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/scsi/3w-9xxx.c 2006-05-11 04:56:24.000000000 +0300 +@@ -85,7 +85,7 @@ + #include "3w-9xxx.h" + + /* Globals */ +-#define TW_DRIVER_VERSION "2.26.02.005" ++#define TW_DRIVER_VERSION "2.26.02.007" + static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT]; + static unsigned int twa_device_extension_count; + static int twa_major = -1; +@@ -1944,9 +1944,13 @@ + } + if (tw_dev->srb[request_id]->use_sg == 1) { + struct scatterlist *sg = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer; +- char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; ++ char *buf; ++ unsigned long flags = 0; ++ local_irq_save(flags); ++ buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length); + kunmap_atomic(buf - sg->offset, KM_IRQ0); ++ local_irq_restore(flags); + } + } + } /* End twa_scsiop_execute_scsi_complete() */ +diff -Naur linux-2.6.16/drivers/scsi/3w-xxxx.c linux-2.6.16.16/drivers/scsi/3w-xxxx.c +--- linux-2.6.16/drivers/scsi/3w-xxxx.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/scsi/3w-xxxx.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1508,10 +1508,12 @@ + struct scsi_cmnd *cmd = tw_dev->srb[request_id]; + void *buf; + unsigned int transfer_len; ++ unsigned long flags = 0; + + if (cmd->use_sg) { + struct scatterlist *sg = + (struct scatterlist *)cmd->request_buffer; ++ local_irq_save(flags); + buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; + transfer_len = min(sg->length, len); + } else { +@@ -1526,6 +1528,7 @@ + + sg = (struct scatterlist *)cmd->request_buffer; + kunmap_atomic(buf - sg->offset, KM_IRQ0); ++ local_irq_restore(flags); + } + } + +diff -Naur linux-2.6.16/drivers/scsi/sata_mv.c linux-2.6.16.16/drivers/scsi/sata_mv.c +--- linux-2.6.16/drivers/scsi/sata_mv.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/scsi/sata_mv.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1102,6 +1102,7 @@ + void __iomem *port_mmio = mv_ap_base(ap); + struct mv_port_priv *pp = ap->private_data; + u32 out_ptr; ++ u8 ata_status; + + out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + +@@ -1109,6 +1110,8 @@ + assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + pp->rsp_consumer); + ++ ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT; ++ + /* increment our consumer index... */ + pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); + +@@ -1123,7 +1126,7 @@ + writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); + + /* Return ATA status register for completed CRPB */ +- return (pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT); ++ return ata_status; + } + + /** +@@ -1192,7 +1195,6 @@ + u32 hc_irq_cause; + int shift, port, port0, hard_port, handled; + unsigned int err_mask; +- u8 ata_status = 0; + + if (hc == 0) { + port0 = 0; +@@ -1210,6 +1212,7 @@ + hc,relevant,hc_irq_cause); + + for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { ++ u8 ata_status = 0; + ap = host_set->ports[port]; + hard_port = port & MV_PORT_MASK; /* range 0-3 */ + handled = 0; /* ensure ata_status is set if handled++ */ +diff -Naur linux-2.6.16/drivers/usb/core/message.c linux-2.6.16.16/drivers/usb/core/message.c +--- linux-2.6.16/drivers/usb/core/message.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/usb/core/message.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1388,11 +1388,13 @@ + if (dev->state != USB_STATE_ADDRESS) + usb_disable_device (dev, 1); // Skip ep0 + +- i = dev->bus_mA - cp->desc.bMaxPower * 2; +- if (i < 0) +- dev_warn(&dev->dev, "new config #%d exceeds power " +- "limit by %dmA\n", +- configuration, -i); ++ if (cp) { ++ i = dev->bus_mA - cp->desc.bMaxPower * 2; ++ if (i < 0) ++ dev_warn(&dev->dev, "new config #%d exceeds power " ++ "limit by %dmA\n", ++ configuration, -i); ++ } + + if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, +diff -Naur linux-2.6.16/drivers/usb/host/ehci-sched.c linux-2.6.16.16/drivers/usb/host/ehci-sched.c +--- linux-2.6.16/drivers/usb/host/ehci-sched.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/usb/host/ehci-sched.c 2006-05-11 04:56:24.000000000 +0300 +@@ -707,6 +707,7 @@ + } else { + u32 addr; + int think_time; ++ int hs_transfers; + + addr = dev->ttport << 24; + if (!ehci_is_TDI(ehci) +@@ -719,6 +720,7 @@ + think_time = dev->tt ? dev->tt->think_time : 0; + stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time ( + dev->speed, is_input, 1, maxp)); ++ hs_transfers = max (1u, (maxp + 187) / 188); + if (is_input) { + u32 tmp; + +@@ -727,12 +729,11 @@ + stream->usecs = HS_USECS_ISO (1); + stream->raw_mask = 1; + +- /* pessimistic c-mask */ +- tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp) +- / (125 * 1000); +- stream->raw_mask |= 3 << (tmp + 9); ++ /* c-mask as specified in USB 2.0 11.18.4 3.c */ ++ tmp = (1 << (hs_transfers + 2)) - 1; ++ stream->raw_mask |= tmp << (8 + 2); + } else +- stream->raw_mask = smask_out [maxp / 188]; ++ stream->raw_mask = smask_out [hs_transfers - 1]; + bandwidth = stream->usecs + stream->c_usecs; + bandwidth /= 1 << (interval + 2); + +diff -Naur linux-2.6.16/drivers/usb/serial/console.c linux-2.6.16.16/drivers/usb/serial/console.c +--- linux-2.6.16/drivers/usb/serial/console.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/usb/serial/console.c 2006-05-11 04:56:24.000000000 +0300 +@@ -54,7 +54,7 @@ + * serial.c code, except that the specifier is "ttyUSB" instead + * of "ttyS". + */ +-static int __init usb_console_setup(struct console *co, char *options) ++static int usb_console_setup(struct console *co, char *options) + { + struct usbcons_info *info = &usbcons_info; + int baud = 9600; +diff -Naur linux-2.6.16/drivers/usb/serial/option.c linux-2.6.16.16/drivers/usb/serial/option.c +--- linux-2.6.16/drivers/usb/serial/option.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/usb/serial/option.c 2006-05-11 04:56:24.000000000 +0300 +@@ -582,14 +582,14 @@ + portdata = usb_get_serial_port_data(port); + + /* Do indat endpoints first */ +- for (j = 0; j <= N_IN_URB; ++j) { ++ for (j = 0; j < N_IN_URB; ++j) { + portdata->in_urbs[j] = option_setup_urb (serial, + port->bulk_in_endpointAddress, USB_DIR_IN, port, + portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); + } + + /* outdat endpoints */ +- for (j = 0; j <= N_OUT_URB; ++j) { ++ for (j = 0; j < N_OUT_URB; ++j) { + portdata->out_urbs[j] = option_setup_urb (serial, + port->bulk_out_endpointAddress, USB_DIR_OUT, port, + portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); +diff -Naur linux-2.6.16/drivers/usb/storage/Kconfig linux-2.6.16.16/drivers/usb/storage/Kconfig +--- linux-2.6.16/drivers/usb/storage/Kconfig 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/usb/storage/Kconfig 2006-05-11 04:56:24.000000000 +0300 +@@ -48,7 +48,8 @@ + + config USB_STORAGE_ISD200 + bool "ISD-200 USB/ATA Bridge support" +- depends on USB_STORAGE && BLK_DEV_IDE ++ depends on USB_STORAGE ++ depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE + ---help--- + Say Y here if you want to use USB Mass Store devices based + on the In-Systems Design ISD-200 USB/ATA bridge. +diff -Naur linux-2.6.16/drivers/video/cfbimgblt.c linux-2.6.16.16/drivers/video/cfbimgblt.c +--- linux-2.6.16/drivers/video/cfbimgblt.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/video/cfbimgblt.c 2006-05-11 04:56:24.000000000 +0300 +@@ -169,7 +169,7 @@ + + while (j--) { + l--; +- color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; ++ color = (*s & (1 << l)) ? fgcolor : bgcolor; + val |= FB_SHIFT_HIGH(color, shift); + + /* Did the bitshift spill bits to the next long? */ +diff -Naur linux-2.6.16/drivers/video/fbmem.c linux-2.6.16.16/drivers/video/fbmem.c +--- linux-2.6.16/drivers/video/fbmem.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/video/fbmem.c 2006-05-11 04:56:24.000000000 +0300 +@@ -669,13 +669,19 @@ + total_size = info->fix.smem_len; + + if (p > total_size) +- return 0; ++ return -EFBIG; + +- if (count >= total_size) ++ if (count > total_size) { ++ err = -EFBIG; + count = total_size; ++ } ++ ++ if (count + p > total_size) { ++ if (!err) ++ err = -ENOSPC; + +- if (count + p > total_size) + count = total_size - p; ++ } + + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, + GFP_KERNEL); +@@ -717,7 +723,7 @@ + + kfree(buffer); + +- return (err) ? err : cnt; ++ return (cnt) ? cnt : err; + } + + #ifdef CONFIG_KMOD +diff -Naur linux-2.6.16/drivers/video/i810/i810_main.c linux-2.6.16.16/drivers/video/i810/i810_main.c +--- linux-2.6.16/drivers/video/i810/i810_main.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/drivers/video/i810/i810_main.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1508,7 +1508,7 @@ + int size = ((cursor->image.width + 7) >> 3) * + cursor->image.height; + int i; +- u8 *data = kmalloc(64 * 8, GFP_KERNEL); ++ u8 *data = kmalloc(64 * 8, GFP_ATOMIC); + + if (data == NULL) + return -ENOMEM; +diff -Naur linux-2.6.16/fs/9p/vfs_inode.c linux-2.6.16.16/fs/9p/vfs_inode.c +--- linux-2.6.16/fs/9p/vfs_inode.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/9p/vfs_inode.c 2006-05-11 04:56:24.000000000 +0300 +@@ -614,6 +614,7 @@ + + sb = dir->i_sb; + v9ses = v9fs_inode2v9ses(dir); ++ dentry->d_op = &v9fs_dentry_operations; + dirfid = v9fs_fid_lookup(dentry->d_parent); + + if (!dirfid) { +@@ -681,8 +682,6 @@ + goto FreeFcall; + + fid->qid = fcall->params.rstat.stat.qid; +- +- dentry->d_op = &v9fs_dentry_operations; + v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); + + d_add(dentry, inode); +diff -Naur linux-2.6.16/fs/char_dev.c linux-2.6.16.16/fs/char_dev.c +--- linux-2.6.16/fs/char_dev.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/char_dev.c 2006-05-11 04:56:24.000000000 +0300 +@@ -15,6 +15,7 @@ + #include <linux/module.h> + #include <linux/smp_lock.h> + #include <linux/devfs_fs_kernel.h> ++#include <linux/seq_file.h> + + #include <linux/kobject.h> + #include <linux/kobj_map.h> +@@ -26,8 +27,6 @@ + + static struct kobj_map *cdev_map; + +-#define MAX_PROBE_HASH 255 /* random */ +- + static DECLARE_MUTEX(chrdevs_lock); + + static struct char_device_struct { +@@ -38,93 +37,29 @@ + char name[64]; + struct file_operations *fops; + struct cdev *cdev; /* will die */ +-} *chrdevs[MAX_PROBE_HASH]; ++} *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; + + /* index in the above */ + static inline int major_to_index(int major) + { +- return major % MAX_PROBE_HASH; +-} +- +-struct chrdev_info { +- int index; +- struct char_device_struct *cd; +-}; +- +-void *get_next_chrdev(void *dev) +-{ +- struct chrdev_info *info; +- +- if (dev == NULL) { +- info = kmalloc(sizeof(*info), GFP_KERNEL); +- if (!info) +- goto out; +- info->index=0; +- info->cd = chrdevs[info->index]; +- if (info->cd) +- goto out; +- } else { +- info = dev; +- } +- +- while (info->index < ARRAY_SIZE(chrdevs)) { +- if (info->cd) +- info->cd = info->cd->next; +- if (info->cd) +- goto out; +- /* +- * No devices on this chain, move to the next +- */ +- info->index++; +- info->cd = (info->index < ARRAY_SIZE(chrdevs)) ? +- chrdevs[info->index] : NULL; +- if (info->cd) +- goto out; +- } +- +-out: +- return info; +-} +- +-void *acquire_chrdev_list(void) +-{ +- down(&chrdevs_lock); +- return get_next_chrdev(NULL); +-} +- +-void release_chrdev_list(void *dev) +-{ +- up(&chrdevs_lock); +- kfree(dev); ++ return major % CHRDEV_MAJOR_HASH_SIZE; + } + ++#ifdef CONFIG_PROC_FS + +-int count_chrdev_list(void) ++void chrdev_show(struct seq_file *f, off_t offset) + { + struct char_device_struct *cd; +- int i, count; +- +- count = 0; + +- for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { +- for (cd = chrdevs[i]; cd; cd = cd->next) +- count++; ++ if (offset < CHRDEV_MAJOR_HASH_SIZE) { ++ down(&chrdevs_lock); ++ for (cd = chrdevs[offset]; cd; cd = cd->next) ++ seq_printf(f, "%3d %s\n", cd->major, cd->name); ++ up(&chrdevs_lock); + } +- +- return count; + } + +-int get_chrdev_info(void *dev, int *major, char **name) +-{ +- struct chrdev_info *info = dev; +- +- if (info->cd == NULL) +- return 1; +- +- *major = info->cd->major; +- *name = info->cd->name; +- return 0; +-} ++#endif /* CONFIG_PROC_FS */ + + /* + * Register a single major with a specified minor range. +diff -Naur linux-2.6.16/fs/cifs/cifsencrypt.c linux-2.6.16.16/fs/cifs/cifsencrypt.c +--- linux-2.6.16/fs/cifs/cifsencrypt.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/cifs/cifsencrypt.c 2006-05-11 04:56:24.000000000 +0300 +@@ -56,9 +56,6 @@ + int rc = 0; + char smb_signature[20]; + +- /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */ +- /* BB remember to add code to save expected sequence number in midQ entry BB */ +- + if((cifs_pdu == NULL) || (server == NULL)) + return -EINVAL; + +@@ -85,20 +82,33 @@ + static int cifs_calc_signature2(const struct kvec * iov, int n_vec, + const char * key, char * signature) + { +- struct MD5Context context; +- +- if((iov == NULL) || (signature == NULL)) +- return -EINVAL; ++ struct MD5Context context; ++ int i; + +- MD5Init(&context); +- MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); ++ if((iov == NULL) || (signature == NULL)) ++ return -EINVAL; + +-/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ ++ MD5Init(&context); ++ MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); ++ for(i=0;i<n_vec;i++) { ++ if(iov[i].iov_base == NULL) { ++ cERROR(1,("null iovec entry")); ++ return -EIO; ++ } else if(iov[i].iov_len == 0) ++ break; /* bail out if we are sent nothing to sign */ ++ /* The first entry includes a length field (which does not get ++ signed that occupies the first 4 bytes before the header */ ++ if(i==0) { ++ if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */ ++ break; /* nothing to sign or corrupt header */ ++ MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4); ++ } else ++ MD5Update(&context,iov[i].iov_base, iov[i].iov_len); ++ } + +- MD5Final(signature,&context); ++ MD5Final(signature,&context); + +- return -EOPNOTSUPP; +-/* return 0; */ ++ return 0; + } + + +diff -Naur linux-2.6.16/fs/cifs/dir.c linux-2.6.16.16/fs/cifs/dir.c +--- linux-2.6.16/fs/cifs/dir.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/cifs/dir.c 2006-05-11 04:56:24.000000000 +0300 +@@ -441,6 +441,20 @@ + cifs_sb = CIFS_SB(parent_dir_inode->i_sb); + pTcon = cifs_sb->tcon; + ++ /* ++ * Don't allow the separator character in a path component. ++ * The VFS will not allow "/", but "\" is allowed by posix. ++ */ ++ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { ++ int i; ++ for (i = 0; i < direntry->d_name.len; i++) ++ if (direntry->d_name.name[i] == '\\') { ++ cFYI(1, ("Invalid file name")); ++ FreeXid(xid); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ + /* can not grab the rename sem here since it would + deadlock in the cases (beginning of sys_rename itself) + in which we already have the sb rename sem */ +diff -Naur linux-2.6.16/fs/compat.c linux-2.6.16.16/fs/compat.c +--- linux-2.6.16/fs/compat.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/compat.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1215,6 +1215,10 @@ + if (ret < 0) + goto out; + ++ ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE); ++ if (ret) ++ goto out; ++ + fnv = NULL; + if (type == READ) { + fn = file->f_op->read; +diff -Naur linux-2.6.16/fs/ext3/resize.c linux-2.6.16.16/fs/ext3/resize.c +--- linux-2.6.16/fs/ext3/resize.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/ext3/resize.c 2006-05-11 04:56:24.000000000 +0300 +@@ -974,6 +974,7 @@ + if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { + ext3_warning(sb, __FUNCTION__, + "multiple resizers run on filesystem!"); ++ unlock_super(sb); + err = -EBUSY; + goto exit_put; + } +diff -Naur linux-2.6.16/fs/fuse/file.c linux-2.6.16.16/fs/fuse/file.c +--- linux-2.6.16/fs/fuse/file.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/fuse/file.c 2006-05-11 04:56:24.000000000 +0300 +@@ -397,8 +397,12 @@ + return -EINTR; + + err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); +- if (!err) +- fuse_send_readpages(data.req, file, inode); ++ if (!err) { ++ if (data.req->num_pages) ++ fuse_send_readpages(data.req, file, inode); ++ else ++ fuse_put_request(fc, data.req); ++ } + return err; + } + +diff -Naur linux-2.6.16/fs/locks.c linux-2.6.16.16/fs/locks.c +--- linux-2.6.16/fs/locks.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/locks.c 2006-05-11 04:56:24.000000000 +0300 +@@ -432,15 +432,14 @@ + */ + static int lease_init(struct file *filp, int type, struct file_lock *fl) + { ++ if (assign_type(fl, type) != 0) ++ return -EINVAL; ++ + fl->fl_owner = current->files; + fl->fl_pid = current->tgid; + + fl->fl_file = filp; + fl->fl_flags = FL_LEASE; +- if (assign_type(fl, type) != 0) { +- locks_free_lock(fl); +- return -EINVAL; +- } + fl->fl_start = 0; + fl->fl_end = OFFSET_MAX; + fl->fl_ops = NULL; +@@ -452,16 +451,19 @@ + static int lease_alloc(struct file *filp, int type, struct file_lock **flp) + { + struct file_lock *fl = locks_alloc_lock(); +- int error; ++ int error = -ENOMEM; + + if (fl == NULL) +- return -ENOMEM; ++ goto out; + + error = lease_init(filp, type, fl); +- if (error) +- return error; ++ if (error) { ++ locks_free_lock(fl); ++ fl = NULL; ++ } ++out: + *flp = fl; +- return 0; ++ return error; + } + + /* Check if two locks overlap each other. +@@ -1337,6 +1339,7 @@ + goto out; + + if (my_before != NULL) { ++ *flp = *my_before; + error = lease->fl_lmops->fl_change(my_before, arg); + goto out; + } +@@ -2212,7 +2215,12 @@ + + lock_kernel(); + j = 0; +- rcu_read_lock(); ++ ++ /* ++ * We are not taking a ref to the file structures, so ++ * we need to acquire ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + fdt = files_fdtable(files); + for (;;) { + unsigned long set; +@@ -2230,7 +2238,7 @@ + set >>= 1; + } + } +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + unlock_kernel(); + } + EXPORT_SYMBOL(steal_locks); +diff -Naur linux-2.6.16/fs/nfsd/nfs3proc.c linux-2.6.16.16/fs/nfsd/nfs3proc.c +--- linux-2.6.16/fs/nfsd/nfs3proc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/nfsd/nfs3proc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -682,7 +682,7 @@ + PROC(lookup, dirop, dirop, fhandle2, RC_NOCACHE, ST+FH+pAT+pAT), + PROC(access, access, access, fhandle, RC_NOCACHE, ST+pAT+1), + PROC(readlink, readlink, readlink, fhandle, RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4), +- PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE), ++ PROC(read, read, read, fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE/4), + PROC(write, write, write, fhandle, RC_REPLBUFF, ST+WC+4), + PROC(create, create, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), + PROC(mkdir, mkdir, create, fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC), +diff -Naur linux-2.6.16/fs/nfsd/nfs4proc.c linux-2.6.16.16/fs/nfsd/nfs4proc.c +--- linux-2.6.16/fs/nfsd/nfs4proc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/nfsd/nfs4proc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -975,7 +975,7 @@ + */ + static struct svc_procedure nfsd_procedures4[2] = { + PROC(null, void, void, void, RC_NOCACHE, 1), +- PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE) ++ PROC(compound, compound, compound, compound, RC_NOCACHE, NFSD_BUFSIZE/4) + }; + + struct svc_version nfsd_version4 = { +diff -Naur linux-2.6.16/fs/nfsd/nfsproc.c linux-2.6.16.16/fs/nfsd/nfsproc.c +--- linux-2.6.16/fs/nfsd/nfsproc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/nfsd/nfsproc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -553,7 +553,7 @@ + PROC(none, void, void, none, RC_NOCACHE, ST), + PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), + PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), +- PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE), ++ PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE/4), + PROC(none, void, void, none, RC_NOCACHE, ST), + PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), + PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), +diff -Naur linux-2.6.16/fs/open.c linux-2.6.16.16/fs/open.c +--- linux-2.6.16/fs/open.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/open.c 2006-05-11 04:56:24.000000000 +0300 +@@ -330,7 +330,10 @@ + + asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) + { +- return do_sys_ftruncate(fd, length, 1); ++ long ret = do_sys_ftruncate(fd, length, 1); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + /* LFS versions of truncate are only needed on 32 bit machines */ +@@ -342,7 +345,10 @@ + + asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) + { +- return do_sys_ftruncate(fd, length, 0); ++ long ret = do_sys_ftruncate(fd, length, 0); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + #endif + +@@ -1083,20 +1089,30 @@ + + asmlinkage long sys_open(const char __user *filename, int flags, int mode) + { ++ long ret; ++ + if (force_o_largefile()) + flags |= O_LARGEFILE; + +- return do_sys_open(AT_FDCWD, filename, flags, mode); ++ ret = do_sys_open(AT_FDCWD, filename, flags, mode); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + EXPORT_SYMBOL_GPL(sys_open); + + asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, + int mode) + { ++ long ret; ++ + if (force_o_largefile()) + flags |= O_LARGEFILE; + +- return do_sys_open(dfd, filename, flags, mode); ++ ret = do_sys_open(dfd, filename, flags, mode); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + EXPORT_SYMBOL_GPL(sys_openat); + +diff -Naur linux-2.6.16/fs/partitions/check.c linux-2.6.16.16/fs/partitions/check.c +--- linux-2.6.16/fs/partitions/check.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/partitions/check.c 2006-05-11 04:56:24.000000000 +0300 +@@ -345,6 +345,7 @@ + char *name; + static char *block_str = "block:"; + int size; ++ char *s; + + size = strlen(block_str) + strlen(disk->disk_name) + 1; + name = kmalloc(size, GFP_KERNEL); +@@ -352,6 +353,10 @@ + return NULL; + strcpy(name, block_str); + strcat(name, disk->disk_name); ++ /* ewww... some of these buggers have / in name... */ ++ s = strchr(name, '/'); ++ if (s) ++ *s = '!'; + return name; + } + +diff -Naur linux-2.6.16/fs/proc/base.c linux-2.6.16.16/fs/proc/base.c +--- linux-2.6.16/fs/proc/base.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/proc/base.c 2006-05-11 04:56:24.000000000 +0300 +@@ -294,16 +294,20 @@ + + files = get_files_struct(task); + if (files) { +- rcu_read_lock(); ++ /* ++ * We are not taking a ref to the file structure, so we must ++ * hold ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (file) { + *mnt = mntget(file->f_vfsmnt); + *dentry = dget(file->f_dentry); +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + return 0; + } +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + } + return -ENOENT; +@@ -1485,7 +1489,12 @@ + if (!files) + goto out_unlock; + inode->i_mode = S_IFLNK; +- rcu_read_lock(); ++ ++ /* ++ * We are not taking a ref to the file structure, so we must ++ * hold ->file_lock. ++ */ ++ spin_lock(&files->file_lock); + file = fcheck_files(files, fd); + if (!file) + goto out_unlock2; +@@ -1493,7 +1502,7 @@ + inode->i_mode |= S_IRUSR | S_IXUSR; + if (file->f_mode & 2) + inode->i_mode |= S_IWUSR | S_IXUSR; +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + inode->i_op = &proc_pid_link_inode_operations; + inode->i_size = 64; +@@ -1503,7 +1512,7 @@ + return NULL; + + out_unlock2: +- rcu_read_unlock(); ++ spin_unlock(&files->file_lock); + put_files_struct(files); + out_unlock: + iput(inode); +diff -Naur linux-2.6.16/fs/proc/proc_misc.c linux-2.6.16.16/fs/proc/proc_misc.c +--- linux-2.6.16/fs/proc/proc_misc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/proc/proc_misc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -249,144 +249,60 @@ + return seq_open(file, &cpuinfo_op); + } + +-enum devinfo_states { +- CHR_HDR, +- CHR_LIST, +- BLK_HDR, +- BLK_LIST, +- DEVINFO_DONE +-}; +- +-struct devinfo_state { +- void *chrdev; +- void *blkdev; +- unsigned int num_records; +- unsigned int cur_record; +- enum devinfo_states state; ++static struct file_operations proc_cpuinfo_operations = { ++ .open = cpuinfo_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, + }; + +-static void *devinfo_start(struct seq_file *f, loff_t *pos) ++static int devinfo_show(struct seq_file *f, void *v) + { +- struct devinfo_state *info = f->private; ++ int i = *(loff_t *) v; + +- if (*pos) { +- if ((info) && (*pos <= info->num_records)) +- return info; +- return NULL; ++ if (i < CHRDEV_MAJOR_HASH_SIZE) { ++ if (i == 0) ++ seq_printf(f, "Character devices:\n"); ++ chrdev_show(f, i); ++ } else { ++ i -= CHRDEV_MAJOR_HASH_SIZE; ++ if (i == 0) ++ seq_printf(f, "\nBlock devices:\n"); ++ blkdev_show(f, i); + } +- info = kmalloc(sizeof(*info), GFP_KERNEL); +- f->private = info; +- info->chrdev = acquire_chrdev_list(); +- info->blkdev = acquire_blkdev_list(); +- info->state = CHR_HDR; +- info->num_records = count_chrdev_list(); +- info->num_records += count_blkdev_list(); +- info->num_records += 2; /* Character and Block headers */ +- *pos = 1; +- info->cur_record = *pos; +- return info; ++ return 0; + } + +-static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) ++static void *devinfo_start(struct seq_file *f, loff_t *pos) + { +- int idummy; +- char *ndummy; +- struct devinfo_state *info = f->private; +- +- switch (info->state) { +- case CHR_HDR: +- info->state = CHR_LIST; +- (*pos)++; +- /*fallthrough*/ +- case CHR_LIST: +- if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) { +- /* +- * The character dev list is complete +- */ +- info->state = BLK_HDR; +- } else { +- info->chrdev = get_next_chrdev(info->chrdev); +- } +- (*pos)++; +- break; +- case BLK_HDR: +- info->state = BLK_LIST; +- (*pos)++; +- break; +- case BLK_LIST: +- if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) { +- /* +- * The block dev list is complete +- */ +- info->state = DEVINFO_DONE; +- } else { +- info->blkdev = get_next_blkdev(info->blkdev); +- } +- (*pos)++; +- break; +- case DEVINFO_DONE: +- (*pos)++; +- info->cur_record = *pos; +- info = NULL; +- break; +- default: +- break; +- } +- if (info) +- info->cur_record = *pos; +- return info; ++ if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) ++ return pos; ++ return NULL; + } + +-static void devinfo_stop(struct seq_file *f, void *v) ++static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) + { +- struct devinfo_state *info = f->private; +- +- if (info) { +- release_chrdev_list(info->chrdev); +- release_blkdev_list(info->blkdev); +- f->private = NULL; +- kfree(info); +- } ++ (*pos)++; ++ if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE)) ++ return NULL; ++ return pos; + } + +-static int devinfo_show(struct seq_file *f, void *arg) ++static void devinfo_stop(struct seq_file *f, void *v) + { +- int major; +- char *name; +- struct devinfo_state *info = f->private; +- +- switch(info->state) { +- case CHR_HDR: +- seq_printf(f,"Character devices:\n"); +- /* fallthrough */ +- case CHR_LIST: +- if (!get_chrdev_info(info->chrdev,&major,&name)) +- seq_printf(f,"%3d %s\n",major,name); +- break; +- case BLK_HDR: +- seq_printf(f,"\nBlock devices:\n"); +- /* fallthrough */ +- case BLK_LIST: +- if (!get_blkdev_info(info->blkdev,&major,&name)) +- seq_printf(f,"%3d %s\n",major,name); +- break; +- default: +- break; +- } +- +- return 0; ++ /* Nothing to do */ + } + +-static struct seq_operations devinfo_op = { +- .start = devinfo_start, +- .next = devinfo_next, +- .stop = devinfo_stop, +- .show = devinfo_show, ++static struct seq_operations devinfo_ops = { ++ .start = devinfo_start, ++ .next = devinfo_next, ++ .stop = devinfo_stop, ++ .show = devinfo_show + }; + +-static int devinfo_open(struct inode *inode, struct file *file) ++static int devinfo_open(struct inode *inode, struct file *filp) + { +- return seq_open(file, &devinfo_op); ++ return seq_open(filp, &devinfo_ops); + } + + static struct file_operations proc_devinfo_operations = { +@@ -396,13 +312,6 @@ + .release = seq_release, + }; + +-static struct file_operations proc_cpuinfo_operations = { +- .open = cpuinfo_open, +- .read = seq_read, +- .llseek = seq_lseek, +- .release = seq_release, +-}; +- + extern struct seq_operations vmstat_op; + static int vmstat_open(struct inode *inode, struct file *file) + { +diff -Naur linux-2.6.16/fs/proc/vmcore.c linux-2.6.16.16/fs/proc/vmcore.c +--- linux-2.6.16/fs/proc/vmcore.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/proc/vmcore.c 2006-05-11 04:56:24.000000000 +0300 +@@ -103,8 +103,8 @@ + size_t buflen, loff_t *fpos) + { + ssize_t acc = 0, tmp; +- size_t tsz, nr_bytes; +- u64 start; ++ size_t tsz; ++ u64 start, nr_bytes; + struct vmcore *curr_m = NULL; + + if (buflen == 0 || *fpos >= vmcore_size) +diff -Naur linux-2.6.16/fs/reiserfs/xattr_acl.c linux-2.6.16.16/fs/reiserfs/xattr_acl.c +--- linux-2.6.16/fs/reiserfs/xattr_acl.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/reiserfs/xattr_acl.c 2006-05-11 04:56:24.000000000 +0300 +@@ -408,8 +408,9 @@ + acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); + reiserfs_read_unlock_xattrs(inode->i_sb); + reiserfs_read_unlock_xattr_i(inode); +- ret = acl ? 1 : 0; +- posix_acl_release(acl); ++ ret = (acl && !IS_ERR(acl)); ++ if (ret) ++ posix_acl_release(acl); + } + + return ret; +diff -Naur linux-2.6.16/fs/smbfs/dir.c linux-2.6.16.16/fs/smbfs/dir.c +--- linux-2.6.16/fs/smbfs/dir.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/smbfs/dir.c 2006-05-11 04:56:24.000000000 +0300 +@@ -434,6 +434,11 @@ + if (dentry->d_name.len > SMB_MAXNAMELEN) + goto out; + ++ /* Do not allow lookup of names with backslashes in */ ++ error = -EINVAL; ++ if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) ++ goto out; ++ + lock_kernel(); + error = smb_proc_getattr(dentry, &finfo); + #ifdef SMBFS_PARANOIA +diff -Naur linux-2.6.16/fs/sysfs/dir.c linux-2.6.16.16/fs/sysfs/dir.c +--- linux-2.6.16/fs/sysfs/dir.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/sysfs/dir.c 2006-05-11 04:56:24.000000000 +0300 +@@ -302,6 +302,7 @@ + * Drop reference from dget() on entrance. + */ + dput(dentry); ++ kobj->dentry = NULL; + } + + int sysfs_rename_dir(struct kobject * kobj, const char *new_name) +diff -Naur linux-2.6.16/fs/sysfs/file.c linux-2.6.16.16/fs/sysfs/file.c +--- linux-2.6.16/fs/sysfs/file.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/sysfs/file.c 2006-05-11 04:56:24.000000000 +0300 +@@ -183,7 +183,7 @@ + return -ENOMEM; + + if (count >= PAGE_SIZE) +- count = PAGE_SIZE; ++ count = PAGE_SIZE - 1; + error = copy_from_user(buffer->page,buf,count); + buffer->needs_read_fill = 1; + return error ? -EFAULT : count; +diff -Naur linux-2.6.16/fs/sysfs/inode.c linux-2.6.16.16/fs/sysfs/inode.c +--- linux-2.6.16/fs/sysfs/inode.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/sysfs/inode.c 2006-05-11 04:56:24.000000000 +0300 +@@ -227,12 +227,16 @@ + void sysfs_hash_and_remove(struct dentry * dir, const char * name) + { + struct sysfs_dirent * sd; +- struct sysfs_dirent * parent_sd = dir->d_fsdata; ++ struct sysfs_dirent * parent_sd; ++ ++ if (!dir) ++ return; + + if (dir->d_inode == NULL) + /* no inode means this hasn't been made visible yet */ + return; + ++ parent_sd = dir->d_fsdata; + mutex_lock(&dir->d_inode->i_mutex); + list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { + if (!sd->s_element) +diff -Naur linux-2.6.16/fs/sysfs/symlink.c linux-2.6.16.16/fs/sysfs/symlink.c +--- linux-2.6.16/fs/sysfs/symlink.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/sysfs/symlink.c 2006-05-11 04:56:24.000000000 +0300 +@@ -66,6 +66,7 @@ + if (!error) + return 0; + ++ kobject_put(target); + kfree(sl->link_name); + exit2: + kfree(sl); +diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c +--- linux-2.6.16/fs/xfs/linux-2.6/xfs_aops.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_aops.c 2006-05-11 04:56:24.000000000 +0300 +@@ -616,7 +616,7 @@ + acceptable = (type == IOMAP_UNWRITTEN); + else if (buffer_delay(bh)) + acceptable = (type == IOMAP_DELAY); +- else if (buffer_mapped(bh)) ++ else if (buffer_dirty(bh) && buffer_mapped(bh)) + acceptable = (type == 0); + else + break; +diff -Naur linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c +--- linux-2.6.16/fs/xfs/linux-2.6/xfs_iops.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/fs/xfs/linux-2.6/xfs_iops.c 2006-05-11 04:56:24.000000000 +0300 +@@ -673,8 +673,7 @@ + if (ia_valid & ATTR_ATIME) { + vattr.va_mask |= XFS_AT_ATIME; + vattr.va_atime = attr->ia_atime; +- if (ia_valid & ATTR_ATIME_SET) +- inode->i_atime = attr->ia_atime; ++ inode->i_atime = attr->ia_atime; + } + if (ia_valid & ATTR_MTIME) { + vattr.va_mask |= XFS_AT_MTIME; +diff -Naur linux-2.6.16/include/asm-i386/cpufeature.h linux-2.6.16.16/include/asm-i386/cpufeature.h +--- linux-2.6.16/include/asm-i386/cpufeature.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-i386/cpufeature.h 2006-05-11 04:56:24.000000000 +0300 +@@ -70,6 +70,7 @@ + #define X86_FEATURE_P3 (3*32+ 6) /* P3 */ + #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ + #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ ++#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ +diff -Naur linux-2.6.16/include/asm-i386/i387.h linux-2.6.16.16/include/asm-i386/i387.h +--- linux-2.6.16/include/asm-i386/i387.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-i386/i387.h 2006-05-11 04:56:24.000000000 +0300 +@@ -13,6 +13,7 @@ + + #include <linux/sched.h> + #include <linux/init.h> ++#include <linux/kernel_stat.h> + #include <asm/processor.h> + #include <asm/sigcontext.h> + #include <asm/user.h> +@@ -38,17 +39,38 @@ + extern void kernel_fpu_begin(void); + #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) + ++/* We need a safe address that is cheap to find and that is already ++ in L1 during context switch. The best choices are unfortunately ++ different for UP and SMP */ ++#ifdef CONFIG_SMP ++#define safe_address (__per_cpu_offset[0]) ++#else ++#define safe_address (kstat_cpu(0).cpustat.user) ++#endif ++ + /* + * These must be called with preempt disabled + */ + static inline void __save_init_fpu( struct task_struct *tsk ) + { ++ /* Use more nops than strictly needed in case the compiler ++ varies code */ + alternative_input( +- "fnsave %1 ; fwait ;" GENERIC_NOP2, +- "fxsave %1 ; fnclex", ++ "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, ++ "fxsave %[fx]\n" ++ "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:", + X86_FEATURE_FXSR, +- "m" (tsk->thread.i387.fxsave) +- :"memory"); ++ [fx] "m" (tsk->thread.i387.fxsave), ++ [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); ++ /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception ++ is pending. Clear the x87 state here by setting it to fixed ++ values. safe_address is a random variable that should be in L1 */ ++ alternative_input( ++ GENERIC_NOP8 GENERIC_NOP2, ++ "emms\n\t" /* clear stack tags */ ++ "fildl %[addr]", /* set F?P to defined value */ ++ X86_FEATURE_FXSAVE_LEAK, ++ [addr] "m" (safe_address)); + task_thread_info(tsk)->status &= ~TS_USEDFPU; + } + +diff -Naur linux-2.6.16/include/asm-i386/pgtable-2level.h linux-2.6.16.16/include/asm-i386/pgtable-2level.h +--- linux-2.6.16/include/asm-i386/pgtable-2level.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-i386/pgtable-2level.h 2006-05-11 04:56:24.000000000 +0300 +@@ -18,6 +18,9 @@ + #define set_pte_atomic(pteptr, pteval) set_pte(pteptr,pteval) + #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) + ++#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) ++#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) ++ + #define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte_low, 0)) + #define pte_same(a, b) ((a).pte_low == (b).pte_low) + #define pte_page(x) pfn_to_page(pte_pfn(x)) +diff -Naur linux-2.6.16/include/asm-i386/pgtable-3level.h linux-2.6.16.16/include/asm-i386/pgtable-3level.h +--- linux-2.6.16/include/asm-i386/pgtable-3level.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-i386/pgtable-3level.h 2006-05-11 04:56:24.000000000 +0300 +@@ -85,6 +85,26 @@ + #define pmd_offset(pud, address) ((pmd_t *) pud_page(*(pud)) + \ + pmd_index(address)) + ++/* ++ * For PTEs and PDEs, we must clear the P-bit first when clearing a page table ++ * entry, so clear the bottom half first and enforce ordering with a compiler ++ * barrier. ++ */ ++static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) ++{ ++ ptep->pte_low = 0; ++ smp_wmb(); ++ ptep->pte_high = 0; ++} ++ ++static inline void pmd_clear(pmd_t *pmd) ++{ ++ u32 *tmp = (u32 *)pmd; ++ *tmp = 0; ++ smp_wmb(); ++ *(tmp + 1) = 0; ++} ++ + static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) + { + pte_t res; +diff -Naur linux-2.6.16/include/asm-i386/pgtable.h linux-2.6.16.16/include/asm-i386/pgtable.h +--- linux-2.6.16/include/asm-i386/pgtable.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-i386/pgtable.h 2006-05-11 04:56:24.000000000 +0300 +@@ -204,12 +204,10 @@ + extern unsigned long pg0[]; + + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) +-#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) + + /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ + #define pmd_none(x) (!(unsigned long)pmd_val(x)) + #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) +-#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) + #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) + + +@@ -269,7 +267,7 @@ + pte_t pte; + if (full) { + pte = *ptep; +- *ptep = __pte(0); ++ pte_clear(mm, addr, ptep); + } else { + pte = ptep_get_and_clear(mm, addr, ptep); + } +diff -Naur linux-2.6.16/include/asm-m32r/smp.h linux-2.6.16.16/include/asm-m32r/smp.h +--- linux-2.6.16/include/asm-m32r/smp.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-m32r/smp.h 2006-05-11 04:56:24.000000000 +0300 +@@ -67,7 +67,8 @@ + #define raw_smp_processor_id() (current_thread_info()->cpu) + + extern cpumask_t cpu_callout_map; +-#define cpu_possible_map cpu_callout_map ++extern cpumask_t cpu_possible_map; ++extern cpumask_t cpu_present_map; + + static __inline__ int hard_smp_processor_id(void) + { +diff -Naur linux-2.6.16/include/asm-m32r/uaccess.h linux-2.6.16.16/include/asm-m32r/uaccess.h +--- linux-2.6.16/include/asm-m32r/uaccess.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-m32r/uaccess.h 2006-05-11 04:56:24.000000000 +0300 +@@ -5,17 +5,9 @@ + * linux/include/asm-m32r/uaccess.h + * + * M32R version. +- * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> ++ * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> + */ + +-#undef UACCESS_DEBUG +- +-#ifdef UACCESS_DEBUG +-#define UAPRINTK(args...) printk(args) +-#else +-#define UAPRINTK(args...) +-#endif /* UACCESS_DEBUG */ +- + /* + * User space memory access functions + */ +@@ -38,27 +30,29 @@ + #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) + + #ifdef CONFIG_MMU ++ + #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) + #define USER_DS MAKE_MM_SEG(PAGE_OFFSET) +-#else +-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) +-#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) +-#endif /* CONFIG_MMU */ +- + #define get_ds() (KERNEL_DS) +-#ifdef CONFIG_MMU + #define get_fs() (current_thread_info()->addr_limit) + #define set_fs(x) (current_thread_info()->addr_limit = (x)) +-#else ++ ++#else /* not CONFIG_MMU */ ++ ++#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) ++#define USER_DS MAKE_MM_SEG(0xFFFFFFFF) ++#define get_ds() (KERNEL_DS) ++ + static inline mm_segment_t get_fs(void) + { +- return USER_DS; ++ return USER_DS; + } + + static inline void set_fs(mm_segment_t s) + { + } +-#endif /* CONFIG_MMU */ ++ ++#endif /* not CONFIG_MMU */ + + #define segment_eq(a,b) ((a).seg == (b).seg) + +@@ -83,9 +77,9 @@ + " subx %0, %0\n" \ + " cmpu %4, %1\n" \ + " subx %0, %5\n" \ +- : "=&r"(flag), "=r"(sum) \ +- : "1"(addr), "r"((int)(size)), \ +- "r"(current_thread_info()->addr_limit.seg), "r"(0) \ ++ : "=&r" (flag), "=r" (sum) \ ++ : "1" (addr), "r" ((int)(size)), \ ++ "r" (current_thread_info()->addr_limit.seg), "r" (0) \ + : "cbit" ); \ + flag; }) + +@@ -113,10 +107,10 @@ + #else + static inline int access_ok(int type, const void *addr, unsigned long size) + { +- extern unsigned long memory_start, memory_end; +- unsigned long val = (unsigned long)addr; ++ extern unsigned long memory_start, memory_end; ++ unsigned long val = (unsigned long)addr; + +- return ((val >= memory_start) && ((val + size) < memory_end)); ++ return ((val >= memory_start) && ((val + size) < memory_end)); + } + #endif /* CONFIG_MMU */ + +@@ -155,39 +149,6 @@ + * accesses to the same area of user memory). + */ + +-extern void __get_user_1(void); +-extern void __get_user_2(void); +-extern void __get_user_4(void); +- +-#ifndef MODULE +-#define __get_user_x(size,ret,x,ptr) \ +- __asm__ __volatile__( \ +- " mv r0, %0\n" \ +- " mv r1, %1\n" \ +- " bl __get_user_" #size "\n" \ +- " mv %0, r0\n" \ +- " mv %1, r1\n" \ +- : "=r"(ret), "=r"(x) \ +- : "0"(ptr) \ +- : "r0", "r1", "r14" ) +-#else /* MODULE */ +-/* +- * Use "jl" instead of "bl" for MODULE +- */ +-#define __get_user_x(size,ret,x,ptr) \ +- __asm__ __volatile__( \ +- " mv r0, %0\n" \ +- " mv r1, %1\n" \ +- " seth lr, #high(__get_user_" #size ")\n" \ +- " or3 lr, lr, #low(__get_user_" #size ")\n" \ +- " jl lr\n" \ +- " mv %0, r0\n" \ +- " mv %1, r1\n" \ +- : "=r"(ret), "=r"(x) \ +- : "0"(ptr) \ +- : "r0", "r1", "r14" ) +-#endif +- + /* Careful: we have to cast the result to the type of the pointer for sign + reasons */ + /** +@@ -208,20 +169,7 @@ + * On error, the variable @x is set to zero. + */ + #define get_user(x,ptr) \ +-({ int __ret_gu; \ +- unsigned long __val_gu; \ +- __chk_user_ptr(ptr); \ +- switch(sizeof (*(ptr))) { \ +- case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ +- case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ +- case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ +- default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ +- } \ +- (x) = (__typeof__(*(ptr)))__val_gu; \ +- __ret_gu; \ +-}) +- +-extern void __put_user_bad(void); ++ __get_user_check((x),(ptr),sizeof(*(ptr))) + + /** + * put_user: - Write a simple value into user space. +@@ -240,8 +188,7 @@ + * Returns zero on success, or -EFAULT on error. + */ + #define put_user(x,ptr) \ +- __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) +- ++ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) + + /** + * __get_user: - Get a simple variable from user space, with less checking. +@@ -264,8 +211,64 @@ + * On error, the variable @x is set to zero. + */ + #define __get_user(x,ptr) \ +- __get_user_nocheck((x),(ptr),sizeof(*(ptr))) ++ __get_user_nocheck((x),(ptr),sizeof(*(ptr))) + ++#define __get_user_nocheck(x,ptr,size) \ ++({ \ ++ long __gu_err = 0; \ ++ unsigned long __gu_val; \ ++ might_sleep(); \ ++ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ ++ (x) = (__typeof__(*(ptr)))__gu_val; \ ++ __gu_err; \ ++}) ++ ++#define __get_user_check(x,ptr,size) \ ++({ \ ++ long __gu_err = -EFAULT; \ ++ unsigned long __gu_val = 0; \ ++ const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ ++ might_sleep(); \ ++ if (access_ok(VERIFY_READ,__gu_addr,size)) \ ++ __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ ++ (x) = (__typeof__(*(ptr)))__gu_val; \ ++ __gu_err; \ ++}) ++ ++extern long __get_user_bad(void); ++ ++#define __get_user_size(x,ptr,size,retval) \ ++do { \ ++ retval = 0; \ ++ __chk_user_ptr(ptr); \ ++ switch (size) { \ ++ case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ ++ case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ ++ case 4: __get_user_asm(x,ptr,retval,""); break; \ ++ default: (x) = __get_user_bad(); \ ++ } \ ++} while (0) ++ ++#define __get_user_asm(x, addr, err, itype) \ ++ __asm__ __volatile__( \ ++ " .fillinsn\n" \ ++ "1: ld"itype" %1,@%2\n" \ ++ " .fillinsn\n" \ ++ "2:\n" \ ++ ".section .fixup,\"ax\"\n" \ ++ " .balign 4\n" \ ++ "3: ldi %0,%3\n" \ ++ " seth r14,#high(2b)\n" \ ++ " or3 r14,r14,#low(2b)\n" \ ++ " jmp r14\n" \ ++ ".previous\n" \ ++ ".section __ex_table,\"a\"\n" \ ++ " .balign 4\n" \ ++ " .long 1b,3b\n" \ ++ ".previous" \ ++ : "=&r" (err), "=&r" (x) \ ++ : "r" (addr), "i" (-EFAULT), "0" (err) \ ++ : "r14", "memory") + + /** + * __put_user: - Write a simple value into user space, with less checking. +@@ -287,11 +290,13 @@ + * Returns zero on success, or -EFAULT on error. + */ + #define __put_user(x,ptr) \ +- __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) ++ __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) ++ + + #define __put_user_nocheck(x,ptr,size) \ + ({ \ + long __pu_err; \ ++ might_sleep(); \ + __put_user_size((x),(ptr),(size),__pu_err); \ + __pu_err; \ + }) +@@ -308,28 +313,28 @@ + }) + + #if defined(__LITTLE_ENDIAN__) +-#define __put_user_u64(x, addr, err) \ +- __asm__ __volatile__( \ +- " .fillinsn\n" \ +- "1: st %L1,@%2\n" \ +- " .fillinsn\n" \ +- "2: st %H1,@(4,%2)\n" \ +- " .fillinsn\n" \ +- "3:\n" \ +- ".section .fixup,\"ax\"\n" \ +- " .balign 4\n" \ +- "4: ldi %0,%3\n" \ +- " seth r14,#high(3b)\n" \ +- " or3 r14,r14,#low(3b)\n" \ +- " jmp r14\n" \ +- ".previous\n" \ +- ".section __ex_table,\"a\"\n" \ +- " .balign 4\n" \ +- " .long 1b,4b\n" \ +- " .long 2b,4b\n" \ +- ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ ++#define __put_user_u64(x, addr, err) \ ++ __asm__ __volatile__( \ ++ " .fillinsn\n" \ ++ "1: st %L1,@%2\n" \ ++ " .fillinsn\n" \ ++ "2: st %H1,@(4,%2)\n" \ ++ " .fillinsn\n" \ ++ "3:\n" \ ++ ".section .fixup,\"ax\"\n" \ ++ " .balign 4\n" \ ++ "4: ldi %0,%3\n" \ ++ " seth r14,#high(3b)\n" \ ++ " or3 r14,r14,#low(3b)\n" \ ++ " jmp r14\n" \ ++ ".previous\n" \ ++ ".section __ex_table,\"a\"\n" \ ++ " .balign 4\n" \ ++ " .long 1b,4b\n" \ ++ " .long 2b,4b\n" \ ++ ".previous" \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + + #elif defined(__BIG_ENDIAN__) +@@ -353,13 +358,15 @@ + " .long 1b,4b\n" \ + " .long 2b,4b\n" \ + ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + #else + #error no endian defined + #endif + ++extern void __put_user_bad(void); ++ + #define __put_user_size(x,ptr,size,retval) \ + do { \ + retval = 0; \ +@@ -398,52 +405,8 @@ + " .balign 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ +- : "=&r"(err) \ +- : "r"(x), "r"(addr), "i"(-EFAULT), "0"(err) \ +- : "r14", "memory") +- +-#define __get_user_nocheck(x,ptr,size) \ +-({ \ +- long __gu_err; \ +- unsigned long __gu_val; \ +- __get_user_size(__gu_val,(ptr),(size),__gu_err); \ +- (x) = (__typeof__(*(ptr)))__gu_val; \ +- __gu_err; \ +-}) +- +-extern long __get_user_bad(void); +- +-#define __get_user_size(x,ptr,size,retval) \ +-do { \ +- retval = 0; \ +- __chk_user_ptr(ptr); \ +- switch (size) { \ +- case 1: __get_user_asm(x,ptr,retval,"ub"); break; \ +- case 2: __get_user_asm(x,ptr,retval,"uh"); break; \ +- case 4: __get_user_asm(x,ptr,retval,""); break; \ +- default: (x) = __get_user_bad(); \ +- } \ +-} while (0) +- +-#define __get_user_asm(x, addr, err, itype) \ +- __asm__ __volatile__( \ +- " .fillinsn\n" \ +- "1: ld"itype" %1,@%2\n" \ +- " .fillinsn\n" \ +- "2:\n" \ +- ".section .fixup,\"ax\"\n" \ +- " .balign 4\n" \ +- "3: ldi %0,%3\n" \ +- " seth r14,#high(2b)\n" \ +- " or3 r14,r14,#low(2b)\n" \ +- " jmp r14\n" \ +- ".previous\n" \ +- ".section __ex_table,\"a\"\n" \ +- " .balign 4\n" \ +- " .long 1b,3b\n" \ +- ".previous" \ +- : "=&r"(err), "=&r"(x) \ +- : "r"(addr), "i"(-EFAULT), "0"(err) \ ++ : "=&r" (err) \ ++ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err) \ + : "r14", "memory") + + /* +@@ -453,7 +416,6 @@ + * anything, so this is accurate. + */ + +- + /* + * Copy To/From Userspace + */ +@@ -511,8 +473,9 @@ + " .long 2b,9b\n" \ + " .long 3b,9b\n" \ + ".previous\n" \ +- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ +- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ ++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ ++ "=&r" (__c) \ ++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ + : "r14", "memory"); \ + } while (0) + +@@ -573,8 +536,9 @@ + " .long 2b,7b\n" \ + " .long 3b,7b\n" \ + ".previous\n" \ +- : "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c) \ +- : "0"(to), "1"(from), "2"(size), "3"(size / 4) \ ++ : "=&r" (__dst), "=&r" (__src), "=&r" (size), \ ++ "=&r" (__c) \ ++ : "0" (to), "1" (from), "2" (size), "3" (size / 4) \ + : "r14", "memory"); \ + } while (0) + +@@ -676,7 +640,7 @@ + #define copy_from_user(to,from,n) \ + ({ \ + might_sleep(); \ +-__generic_copy_from_user((to),(from),(n)); \ ++ __generic_copy_from_user((to),(from),(n)); \ + }) + + long __must_check strncpy_from_user(char *dst, const char __user *src, +diff -Naur linux-2.6.16/include/asm-mips/bitops.h linux-2.6.16.16/include/asm-mips/bitops.h +--- linux-2.6.16/include/asm-mips/bitops.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-mips/bitops.h 2006-05-11 04:56:24.000000000 +0300 +@@ -654,7 +654,12 @@ + { + #ifdef CONFIG_32BIT + #ifdef CONFIG_CPU_MIPS32 +- __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); ++ __asm__ ( ++ " .set mips32 \n" ++ " clz %0, %1 \n" ++ " .set mips0 \n" ++ : "=r" (word) ++ : "r" (word)); + + return 32 - word; + #else +@@ -678,7 +683,12 @@ + #ifdef CONFIG_64BIT + #ifdef CONFIG_CPU_MIPS64 + +- __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); ++ __asm__ ( ++ " .set mips64 \n" ++ " dclz %0, %1 \n" ++ " .set mips0 \n" ++ : "=r" (word) ++ : "r" (word)); + + return 64 - word; + #else +diff -Naur linux-2.6.16/include/asm-mips/byteorder.h linux-2.6.16.16/include/asm-mips/byteorder.h +--- linux-2.6.16/include/asm-mips/byteorder.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-mips/byteorder.h 2006-05-11 04:56:24.000000000 +0300 +@@ -19,7 +19,9 @@ + static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) + { + __asm__( ++ " .set mips32r2 \n" + " wsbh %0, %1 \n" ++ " .set mips0 \n" + : "=r" (x) + : "r" (x)); + +@@ -30,8 +32,10 @@ + static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) + { + __asm__( ++ " .set mips32r2 \n" + " wsbh %0, %1 \n" + " rotr %0, %0, 16 \n" ++ " .set mips0 \n" + : "=r" (x) + : "r" (x)); + +diff -Naur linux-2.6.16/include/asm-mips/interrupt.h linux-2.6.16.16/include/asm-mips/interrupt.h +--- linux-2.6.16/include/asm-mips/interrupt.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-mips/interrupt.h 2006-05-11 04:56:24.000000000 +0300 +@@ -20,7 +20,9 @@ + " .set reorder \n" + " .set noat \n" + #ifdef CONFIG_CPU_MIPSR2 ++ " .set mips32r2 \n" + " ei \n" ++ " .set mips0 \n" + #else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" +@@ -63,7 +65,9 @@ + " .set push \n" + " .set noat \n" + #ifdef CONFIG_CPU_MIPSR2 ++ " .set mips32r2 \n" + " di \n" ++ " .set mips0 \n" + #else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" +@@ -103,8 +107,10 @@ + " .set reorder \n" + " .set noat \n" + #ifdef CONFIG_CPU_MIPSR2 ++ " .set mips32r2 \n" + " di \\result \n" + " andi \\result, 1 \n" ++ " .set mips0 \n" + #else + " mfc0 \\result, $12 \n" + " ori $1, \\result, 0x1f \n" +@@ -133,9 +139,11 @@ + * Slow, but doesn't suffer from a relativly unlikely race + * condition we're having since days 1. + */ ++ " .set mips32r2 \n" + " beqz \\flags, 1f \n" + " di \n" + " ei \n" ++ " .set mips0 \n" + "1: \n" + #elif defined(CONFIG_CPU_MIPSR2) + /* +diff -Naur linux-2.6.16/include/asm-mips/r4kcache.h linux-2.6.16.16/include/asm-mips/r4kcache.h +--- linux-2.6.16/include/asm-mips/r4kcache.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-mips/r4kcache.h 2006-05-11 04:56:24.000000000 +0300 +@@ -37,7 +37,7 @@ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ +- : "i" (op), "m" (*(unsigned char *)(addr))) ++ : "i" (op), "R" (*(unsigned char *)(addr))) + + static inline void flush_icache_line_indexed(unsigned long addr) + { +diff -Naur linux-2.6.16/include/asm-powerpc/floppy.h linux-2.6.16.16/include/asm-powerpc/floppy.h +--- linux-2.6.16/include/asm-powerpc/floppy.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-powerpc/floppy.h 2006-05-11 04:56:24.000000000 +0300 +@@ -35,6 +35,7 @@ + #ifdef CONFIG_PCI + + #include <linux/pci.h> ++#include <asm/ppc-pci.h> /* for ppc64_isabridge_dev */ + + #define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) + +@@ -52,12 +53,12 @@ + if (bus_addr + && (addr != prev_addr || size != prev_size || dir != prev_dir)) { + /* different from last time -- unmap prev */ +- pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); ++ pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir); + bus_addr = 0; + } + + if (!bus_addr) /* need to map it */ +- bus_addr = pci_map_single(NULL, addr, size, dir); ++ bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir); + + /* remember this one as prev */ + prev_addr = addr; +diff -Naur linux-2.6.16/include/asm-x86_64/cpufeature.h linux-2.6.16.16/include/asm-x86_64/cpufeature.h +--- linux-2.6.16/include/asm-x86_64/cpufeature.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-x86_64/cpufeature.h 2006-05-11 04:56:24.000000000 +0300 +@@ -64,6 +64,7 @@ + #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ + #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ + #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ ++#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ + + /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ + #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ +diff -Naur linux-2.6.16/include/asm-x86_64/i387.h linux-2.6.16.16/include/asm-x86_64/i387.h +--- linux-2.6.16/include/asm-x86_64/i387.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/asm-x86_64/i387.h 2006-05-11 04:56:24.000000000 +0300 +@@ -72,6 +72,23 @@ + #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) + #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) + ++#define X87_FSW_ES (1 << 7) /* Exception Summary */ ++ ++/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception ++ is pending. Clear the x87 state here by setting it to fixed ++ values. The kernel data segment can be sometimes 0 and sometimes ++ new user value. Both should be ok. ++ Use the PDA as safe address because it should be already in L1. */ ++static inline void clear_fpu_state(struct i387_fxsave_struct *fx) ++{ ++ if (unlikely(fx->swd & X87_FSW_ES)) ++ asm volatile("fnclex"); ++ alternative_input(ASM_NOP8 ASM_NOP2, ++ " emms\n" /* clear stack tags */ ++ " fildl %%gs:0", /* load to clear state */ ++ X86_FEATURE_FXSAVE_LEAK); ++} ++ + static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) + { + int err; +@@ -119,6 +136,7 @@ + #endif + if (unlikely(err)) + __clear_user(fx, sizeof(struct i387_fxsave_struct)); ++ /* No need to clear here because the caller clears USED_MATH */ + return err; + } + +@@ -149,7 +167,7 @@ + "i" (offsetof(__typeof__(*tsk), + thread.i387.fxsave))); + #endif +- __asm__ __volatile__("fnclex"); ++ clear_fpu_state(&tsk->thread.i387.fxsave); + } + + static inline void kernel_fpu_begin(void) +diff -Naur linux-2.6.16/include/linux/cpu.h linux-2.6.16.16/include/linux/cpu.h +--- linux-2.6.16/include/linux/cpu.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/cpu.h 2006-05-11 04:56:24.000000000 +0300 +@@ -32,7 +32,7 @@ + }; + + extern int register_cpu(struct cpu *, int, struct node *); +-extern struct sys_device *get_cpu_sysdev(int cpu); ++extern struct sys_device *get_cpu_sysdev(unsigned cpu); + #ifdef CONFIG_HOTPLUG_CPU + extern void unregister_cpu(struct cpu *, struct node *); + #endif +diff -Naur linux-2.6.16/include/linux/cpumask.h linux-2.6.16.16/include/linux/cpumask.h +--- linux-2.6.16/include/linux/cpumask.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/cpumask.h 2006-05-11 04:56:24.000000000 +0300 +@@ -408,6 +408,7 @@ + }) + + #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) ++#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) + #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) + #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) + +diff -Naur linux-2.6.16/include/linux/fb.h linux-2.6.16.16/include/linux/fb.h +--- linux-2.6.16/include/linux/fb.h 2006-05-18 01:12:24.000000000 +0300 ++++ linux-2.6.16.16/include/linux/fb.h 2006-05-17 21:41:31.000000000 +0300 +@@ -840,12 +840,10 @@ + #define FB_LEFT_POS(bpp) (32 - bpp) + #define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) + #define FB_SHIFT_LOW(val, bits) ((val) << (bits)) +-#define FB_BIT_NR(b) (7 - (b)) + #else + #define FB_LEFT_POS(bpp) (0) + #define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) + #define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) +-#define FB_BIT_NR(b) (b) + #endif + + /* +diff -Naur linux-2.6.16/include/linux/fs.h linux-2.6.16.16/include/linux/fs.h +--- linux-2.6.16/include/linux/fs.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/fs.h 2006-05-11 04:56:24.000000000 +0300 +@@ -1383,6 +1383,7 @@ + extern void bd_release(struct block_device *); + + /* fs/char_dev.c */ ++#define CHRDEV_MAJOR_HASH_SIZE 255 + extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); + extern int register_chrdev_region(dev_t, unsigned, const char *); + extern int register_chrdev(unsigned int, const char *, +@@ -1390,25 +1391,17 @@ + extern int unregister_chrdev(unsigned int, const char *); + extern void unregister_chrdev_region(dev_t, unsigned); + extern int chrdev_open(struct inode *, struct file *); +-extern int get_chrdev_list(char *); +-extern void *acquire_chrdev_list(void); +-extern int count_chrdev_list(void); +-extern void *get_next_chrdev(void *); +-extern int get_chrdev_info(void *, int *, char **); +-extern void release_chrdev_list(void *); ++extern void chrdev_show(struct seq_file *,off_t); + + /* fs/block_dev.c */ ++#define BLKDEV_MAJOR_HASH_SIZE 255 + #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ + extern const char *__bdevname(dev_t, char *buffer); + extern const char *bdevname(struct block_device *bdev, char *buffer); + extern struct block_device *lookup_bdev(const char *); + extern struct block_device *open_bdev_excl(const char *, int, void *); + extern void close_bdev_excl(struct block_device *); +-extern void *acquire_blkdev_list(void); +-extern int count_blkdev_list(void); +-extern void *get_next_blkdev(void *); +-extern int get_blkdev_info(void *, int *, char **); +-extern void release_blkdev_list(void *); ++extern void blkdev_show(struct seq_file *,off_t); + + extern void init_special_inode(struct inode *, umode_t, dev_t); + +diff -Naur linux-2.6.16/include/linux/mm.h linux-2.6.16.16/include/linux/mm.h +--- linux-2.6.16/include/linux/mm.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/mm.h 2006-05-11 04:56:24.000000000 +0300 +@@ -229,10 +229,9 @@ + unsigned long private; /* Mapping-private opaque data: + * usually used for buffer_heads + * if PagePrivate set; used for +- * swp_entry_t if PageSwapCache. +- * When page is free, this ++ * swp_entry_t if PageSwapCache; + * indicates order in the buddy +- * system. ++ * system if PG_buddy is set. + */ + struct address_space *mapping; /* If low bit clear, points to + * inode address_space, or NULL. +diff -Naur linux-2.6.16/include/linux/page-flags.h linux-2.6.16.16/include/linux/page-flags.h +--- linux-2.6.16/include/linux/page-flags.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/page-flags.h 2006-05-11 04:56:24.000000000 +0300 +@@ -74,7 +74,9 @@ + #define PG_mappedtodisk 16 /* Has blocks allocated on-disk */ + #define PG_reclaim 17 /* To be reclaimed asap */ + #define PG_nosave_free 18 /* Free, should not be written */ +-#define PG_uncached 19 /* Page has been mapped as uncached */ ++#define PG_buddy 19 /* Page is free, on buddy lists */ ++ ++#define PG_uncached 20 /* Page has been mapped as uncached */ + + /* + * Global page accounting. One instance per CPU. Only unsigned longs are +@@ -319,6 +321,10 @@ + #define SetPageNosaveFree(page) set_bit(PG_nosave_free, &(page)->flags) + #define ClearPageNosaveFree(page) clear_bit(PG_nosave_free, &(page)->flags) + ++#define PageBuddy(page) test_bit(PG_buddy, &(page)->flags) ++#define __SetPageBuddy(page) __set_bit(PG_buddy, &(page)->flags) ++#define __ClearPageBuddy(page) __clear_bit(PG_buddy, &(page)->flags) ++ + #define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags) + #define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags) + #define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags) +diff -Naur linux-2.6.16/include/linux/proc_fs.h linux-2.6.16.16/include/linux/proc_fs.h +--- linux-2.6.16/include/linux/proc_fs.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/proc_fs.h 2006-05-11 04:56:24.000000000 +0300 +@@ -78,7 +78,7 @@ + struct vmcore { + struct list_head list; + unsigned long long paddr; +- unsigned long size; ++ unsigned long long size; + loff_t offset; + }; + +diff -Naur linux-2.6.16/include/linux/raid/raid1.h linux-2.6.16.16/include/linux/raid/raid1.h +--- linux-2.6.16/include/linux/raid/raid1.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/raid/raid1.h 2006-05-11 04:56:24.000000000 +0300 +@@ -130,6 +130,6 @@ + * with failure when last write completes (and all failed). + * Record that bi_end_io was called with this flag... + */ +-#define R1BIO_Returned 4 ++#define R1BIO_Returned 6 + + #endif +diff -Naur linux-2.6.16/include/linux/rtc.h linux-2.6.16.16/include/linux/rtc.h +--- linux-2.6.16/include/linux/rtc.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/linux/rtc.h 2006-05-11 04:56:24.000000000 +0300 +@@ -11,8 +11,6 @@ + #ifndef _LINUX_RTC_H_ + #define _LINUX_RTC_H_ + +-#include <linux/interrupt.h> +- + /* + * The struct used to pass data via the following ioctl. Similar to the + * struct tm in <time.h>, but it needs to be here so that the kernel +@@ -95,6 +93,8 @@ + + #ifdef __KERNEL__ + ++#include <linux/interrupt.h> ++ + typedef struct rtc_task { + void (*func)(void *private_data); + void *private_data; +diff -Naur linux-2.6.16/include/net/ip.h linux-2.6.16.16/include/net/ip.h +--- linux-2.6.16/include/net/ip.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/net/ip.h 2006-05-11 04:56:24.000000000 +0300 +@@ -95,6 +95,7 @@ + extern int ip_mr_input(struct sk_buff *skb); + extern int ip_output(struct sk_buff *skb); + extern int ip_mc_output(struct sk_buff *skb); ++extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); + extern int ip_do_nat(struct sk_buff *skb); + extern void ip_send_check(struct iphdr *ip); + extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); +diff -Naur linux-2.6.16/include/net/sctp/structs.h linux-2.6.16.16/include/net/sctp/structs.h +--- linux-2.6.16/include/net/sctp/structs.h 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/include/net/sctp/structs.h 2006-05-11 04:56:24.000000000 +0300 +@@ -702,6 +702,7 @@ + __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ + __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ + __u8 tsn_missing_report; /* Data chunk missing counter. */ ++ __u8 data_accepted; /* At least 1 chunk in this packet accepted */ + }; + + void sctp_chunk_hold(struct sctp_chunk *); +diff -Naur linux-2.6.16/ipc/shm.c linux-2.6.16.16/ipc/shm.c +--- linux-2.6.16/ipc/shm.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/ipc/shm.c 2006-05-11 04:56:24.000000000 +0300 +@@ -161,6 +161,8 @@ + ret = shmem_mmap(file, vma); + if (ret == 0) { + vma->vm_ops = &shm_vm_ops; ++ if (!(vma->vm_flags & VM_WRITE)) ++ vma->vm_flags &= ~VM_MAYWRITE; + shm_inc(file->f_dentry->d_inode->i_ino); + } + +diff -Naur linux-2.6.16/ipc/util.c linux-2.6.16.16/ipc/util.c +--- linux-2.6.16/ipc/util.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/ipc/util.c 2006-05-11 04:56:24.000000000 +0300 +@@ -182,8 +182,7 @@ + if(new == NULL) + return size; + new->size = newsize; +- memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size + +- sizeof(struct ipc_id_ary)); ++ memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size); + for(i=size;i<newsize;i++) { + new->p[i] = NULL; + } +diff -Naur linux-2.6.16/kernel/auditsc.c linux-2.6.16.16/kernel/auditsc.c +--- linux-2.6.16/kernel/auditsc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/auditsc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -966,11 +966,6 @@ + if (context->in_syscall) { + struct audit_context *newctx; + +-#if defined(__NR_vm86) && defined(__NR_vm86old) +- /* vm86 mode should only be entered once */ +- if (major == __NR_vm86 || major == __NR_vm86old) +- return; +-#endif + #if AUDIT_DEBUG + printk(KERN_ERR + "audit(:%d) pid=%d in syscall=%d;" +diff -Naur linux-2.6.16/kernel/exec_domain.c linux-2.6.16.16/kernel/exec_domain.c +--- linux-2.6.16/kernel/exec_domain.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/exec_domain.c 2006-05-11 04:56:24.000000000 +0300 +@@ -140,6 +140,7 @@ + ep = lookup_exec_domain(personality); + if (ep == current_thread_info()->exec_domain) { + current->personality = personality; ++ module_put(ep->module); + return 0; + } + +diff -Naur linux-2.6.16/kernel/fork.c linux-2.6.16.16/kernel/fork.c +--- linux-2.6.16/kernel/fork.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/fork.c 2006-05-11 04:56:24.000000000 +0300 +@@ -720,7 +720,7 @@ + free_fdset (new_fdt->open_fds, new_fdt->max_fdset); + free_fd_array(new_fdt->fd, new_fdt->max_fds); + kmem_cache_free(files_cachep, newf); +- goto out; ++ return NULL; + } + + static int copy_files(unsigned long clone_flags, struct task_struct * tsk) +diff -Naur linux-2.6.16/kernel/power/process.c linux-2.6.16.16/kernel/power/process.c +--- linux-2.6.16/kernel/power/process.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/power/process.c 2006-05-11 04:56:24.000000000 +0300 +@@ -25,8 +25,7 @@ + (p->flags & PF_NOFREEZE) || + (p->exit_state == EXIT_ZOMBIE) || + (p->exit_state == EXIT_DEAD) || +- (p->state == TASK_STOPPED) || +- (p->state == TASK_TRACED)) ++ (p->state == TASK_STOPPED)) + return 0; + return 1; + } +diff -Naur linux-2.6.16/kernel/ptrace.c linux-2.6.16.16/kernel/ptrace.c +--- linux-2.6.16/kernel/ptrace.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/ptrace.c 2006-05-11 04:56:24.000000000 +0300 +@@ -57,10 +57,6 @@ + signal_wake_up(child, 1); + } + } +- if (child->signal->flags & SIGNAL_GROUP_EXIT) { +- sigaddset(&child->pending.signal, SIGKILL); +- signal_wake_up(child, 1); +- } + spin_unlock(&child->sighand->siglock); + } + +@@ -82,7 +78,8 @@ + SET_LINKS(child); + } + +- ptrace_untrace(child); ++ if (child->state == TASK_TRACED) ++ ptrace_untrace(child); + } + + /* +diff -Naur linux-2.6.16/kernel/sched.c linux-2.6.16.16/kernel/sched.c +--- linux-2.6.16/kernel/sched.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/sched.c 2006-05-11 04:56:24.000000000 +0300 +@@ -237,6 +237,7 @@ + + task_t *migration_thread; + struct list_head migration_queue; ++ int cpu; + #endif + + #ifdef CONFIG_SCHEDSTATS +@@ -1660,6 +1661,9 @@ + /* + * double_rq_lock - safely lock two runqueues + * ++ * We must take them in cpu order to match code in ++ * dependent_sleeper and wake_dependent_sleeper. ++ * + * Note this does not disable interrupts like task_rq_lock, + * you need to do so manually before calling. + */ +@@ -1671,7 +1675,7 @@ + spin_lock(&rq1->lock); + __acquire(rq2->lock); /* Fake it out ;) */ + } else { +- if (rq1 < rq2) { ++ if (rq1->cpu < rq2->cpu) { + spin_lock(&rq1->lock); + spin_lock(&rq2->lock); + } else { +@@ -1707,7 +1711,7 @@ + __acquires(this_rq->lock) + { + if (unlikely(!spin_trylock(&busiest->lock))) { +- if (busiest < this_rq) { ++ if (busiest->cpu < this_rq->cpu) { + spin_unlock(&this_rq->lock); + spin_lock(&busiest->lock); + spin_lock(&this_rq->lock); +@@ -6035,6 +6039,7 @@ + rq->push_cpu = 0; + rq->migration_thread = NULL; + INIT_LIST_HEAD(&rq->migration_queue); ++ rq->cpu = i; + #endif + atomic_set(&rq->nr_iowait, 0); + +diff -Naur linux-2.6.16/kernel/signal.c linux-2.6.16.16/kernel/signal.c +--- linux-2.6.16/kernel/signal.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/signal.c 2006-05-11 04:56:24.000000000 +0300 +@@ -975,7 +975,6 @@ + if (t == NULL) + /* restart balancing at this thread */ + t = p->signal->curr_target = p; +- BUG_ON(t->tgid != p->tgid); + + while (!wants_signal(sig, t)) { + t = next_thread(t); +@@ -1689,6 +1688,7 @@ + /* Let the debugger run. */ + set_current_state(TASK_TRACED); + spin_unlock_irq(¤t->sighand->siglock); ++ try_to_freeze(); + read_lock(&tasklist_lock); + if (likely(current->ptrace & PT_PTRACED) && + likely(current->parent != current->real_parent || +@@ -1942,9 +1942,9 @@ + /* Let the debugger run. */ + ptrace_stop(signr, signr, info); + +- /* We're back. Did the debugger cancel the sig or group_exit? */ ++ /* We're back. Did the debugger cancel the sig? */ + signr = current->exit_code; +- if (signr == 0 || current->signal->flags & SIGNAL_GROUP_EXIT) ++ if (signr == 0) + continue; + + current->exit_code = 0; +diff -Naur linux-2.6.16/kernel/sys.c linux-2.6.16.16/kernel/sys.c +--- linux-2.6.16/kernel/sys.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/sys.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1657,7 +1657,19 @@ + (cputime_eq(current->signal->it_prof_expires, cputime_zero) || + new_rlim.rlim_cur <= cputime_to_secs( + current->signal->it_prof_expires))) { +- cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur); ++ unsigned long rlim_cur = new_rlim.rlim_cur; ++ cputime_t cputime; ++ ++ if (rlim_cur == 0) { ++ /* ++ * The caller is asking for an immediate RLIMIT_CPU ++ * expiry. But we use the zero value to mean "it was ++ * never set". So let's cheat and make it one second ++ * instead ++ */ ++ rlim_cur = 1; ++ } ++ cputime = secs_to_cputime(rlim_cur); + read_lock(&tasklist_lock); + spin_lock_irq(¤t->sighand->siglock); + set_process_cpu_timer(current, CPUCLOCK_PROF, +diff -Naur linux-2.6.16/kernel/uid16.c linux-2.6.16.16/kernel/uid16.c +--- linux-2.6.16/kernel/uid16.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/kernel/uid16.c 2006-05-11 04:56:24.000000000 +0300 +@@ -20,43 +20,67 @@ + + asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) + { +- return sys_chown(filename, low2highuid(user), low2highgid(group)); ++ long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) + { +- return sys_lchown(filename, low2highuid(user), low2highgid(group)); ++ long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) + { +- return sys_fchown(fd, low2highuid(user), low2highgid(group)); ++ long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) + { +- return sys_setregid(low2highgid(rgid), low2highgid(egid)); ++ long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setgid16(old_gid_t gid) + { +- return sys_setgid(low2highgid(gid)); ++ long ret = sys_setgid(low2highgid(gid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) + { +- return sys_setreuid(low2highuid(ruid), low2highuid(euid)); ++ long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setuid16(old_uid_t uid) + { +- return sys_setuid(low2highuid(uid)); ++ long ret = sys_setuid(low2highuid(uid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) + { +- return sys_setresuid(low2highuid(ruid), low2highuid(euid), +- low2highuid(suid)); ++ long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), ++ low2highuid(suid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) +@@ -72,8 +96,11 @@ + + asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) + { +- return sys_setresgid(low2highgid(rgid), low2highgid(egid), +- low2highgid(sgid)); ++ long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), ++ low2highgid(sgid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) +@@ -89,12 +116,18 @@ + + asmlinkage long sys_setfsuid16(old_uid_t uid) + { +- return sys_setfsuid(low2highuid(uid)); ++ long ret = sys_setfsuid(low2highuid(uid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + asmlinkage long sys_setfsgid16(old_gid_t gid) + { +- return sys_setfsgid(low2highgid(gid)); ++ long ret = sys_setfsgid(low2highgid(gid)); ++ /* avoid REGPARM breakage on x86: */ ++ prevent_tail_call(ret); ++ return ret; + } + + static int groups16_to_user(old_gid_t __user *grouplist, +diff -Naur linux-2.6.16/Makefile linux-2.6.16.16/Makefile +--- linux-2.6.16/Makefile 2006-05-18 01:12:20.000000000 +0300 ++++ linux-2.6.16.16/Makefile 2006-05-17 21:41:27.000000000 +0300 +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 16 +-EXTRAVERSION = ++EXTRAVERSION = .16 + NAME=Sliding Snow Leopard + + # *DOCUMENTATION* +diff -Naur linux-2.6.16/mm/madvise.c linux-2.6.16.16/mm/madvise.c +--- linux-2.6.16/mm/madvise.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/mm/madvise.c 2006-05-11 04:56:24.000000000 +0300 +@@ -168,6 +168,9 @@ + return -EINVAL; + } + ++ if ((vma->vm_flags & (VM_SHARED|VM_WRITE)) != (VM_SHARED|VM_WRITE)) ++ return -EACCES; ++ + mapping = vma->vm_file->f_mapping; + + offset = (loff_t)(start - vma->vm_start) +diff -Naur linux-2.6.16/mm/page_alloc.c linux-2.6.16.16/mm/page_alloc.c +--- linux-2.6.16/mm/page_alloc.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/mm/page_alloc.c 2006-05-11 04:56:24.000000000 +0300 +@@ -153,7 +153,8 @@ + 1 << PG_reclaim | + 1 << PG_slab | + 1 << PG_swapcache | +- 1 << PG_writeback ); ++ 1 << PG_writeback | ++ 1 << PG_buddy ); + set_page_count(page, 0); + reset_page_mapcount(page); + page->mapping = NULL; +@@ -224,12 +225,12 @@ + + static inline void set_page_order(struct page *page, int order) { + set_page_private(page, order); +- __SetPagePrivate(page); ++ __SetPageBuddy(page); + } + + static inline void rmv_page_order(struct page *page) + { +- __ClearPagePrivate(page); ++ __ClearPageBuddy(page); + set_page_private(page, 0); + } + +@@ -268,11 +269,13 @@ + * This function checks whether a page is free && is the buddy + * we can do coalesce a page and its buddy if + * (a) the buddy is not in a hole && +- * (b) the buddy is free && +- * (c) the buddy is on the buddy system && +- * (d) a page and its buddy have the same order. +- * for recording page's order, we use page_private(page) and PG_private. ++ * (b) the buddy is in the buddy system && ++ * (c) a page and its buddy have the same order. ++ * ++ * For recording whether a page is in the buddy system, we use PG_buddy. ++ * Setting, clearing, and testing PG_buddy is serialized by zone->lock. + * ++ * For recording page's order, we use page_private(page). + */ + static inline int page_is_buddy(struct page *page, int order) + { +@@ -281,10 +284,10 @@ + return 0; + #endif + +- if (PagePrivate(page) && +- (page_order(page) == order) && +- page_count(page) == 0) ++ if (PageBuddy(page) && page_order(page) == order) { ++ BUG_ON(page_count(page) != 0); + return 1; ++ } + return 0; + } + +@@ -301,7 +304,7 @@ + * as necessary, plus some accounting needed to play nicely with other + * parts of the VM system. + * At each level, we keep a list of pages, which are heads of continuous +- * free pages of length of (1 << order) and marked with PG_Private.Page's ++ * free pages of length of (1 << order) and marked with PG_buddy. Page's + * order is recorded in page_private(page) field. + * So when we are allocating or freeing one, we can derive the state of the + * other. That is, if we allocate a small block, and both were +@@ -364,7 +367,8 @@ + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | +- 1 << PG_reserved )))) ++ 1 << PG_reserved | ++ 1 << PG_buddy )))) + bad_page(page); + if (PageDirty(page)) + __ClearPageDirty(page); +@@ -522,7 +526,8 @@ + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | +- 1 << PG_reserved )))) ++ 1 << PG_reserved | ++ 1 << PG_buddy )))) + bad_page(page); + + /* +diff -Naur linux-2.6.16/net/atm/clip.c linux-2.6.16.16/net/atm/clip.c +--- linux-2.6.16/net/atm/clip.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/atm/clip.c 2006-05-11 04:56:24.000000000 +0300 +@@ -613,12 +613,19 @@ + + + static int clip_device_event(struct notifier_block *this,unsigned long event, +- void *dev) ++ void *arg) + { ++ struct net_device *dev = arg; ++ ++ if (event == NETDEV_UNREGISTER) { ++ neigh_ifdown(&clip_tbl, dev); ++ return NOTIFY_DONE; ++ } ++ + /* ignore non-CLIP devices */ +- if (((struct net_device *) dev)->type != ARPHRD_ATM || +- ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit) ++ if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit) + return NOTIFY_DONE; ++ + switch (event) { + case NETDEV_UP: + DPRINTK("clip_device_event NETDEV_UP\n"); +@@ -686,14 +693,12 @@ + static void atmarpd_close(struct atm_vcc *vcc) + { + DPRINTK("atmarpd_close\n"); +- atmarpd = NULL; /* assumed to be atomic */ +- barrier(); +- unregister_inetaddr_notifier(&clip_inet_notifier); +- unregister_netdevice_notifier(&clip_dev_notifier); +- if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) +- printk(KERN_ERR "atmarpd_close: closing with requests " +- "pending\n"); ++ ++ rtnl_lock(); ++ atmarpd = NULL; + skb_queue_purge(&sk_atm(vcc)->sk_receive_queue); ++ rtnl_unlock(); ++ + DPRINTK("(done)\n"); + module_put(THIS_MODULE); + } +@@ -714,7 +719,12 @@ + + static int atm_init_atmarp(struct atm_vcc *vcc) + { +- if (atmarpd) return -EADDRINUSE; ++ rtnl_lock(); ++ if (atmarpd) { ++ rtnl_unlock(); ++ return -EADDRINUSE; ++ } ++ + if (start_timer) { + start_timer = 0; + init_timer(&idle_timer); +@@ -731,10 +741,7 @@ + vcc->push = NULL; + vcc->pop = NULL; /* crash */ + vcc->push_oam = NULL; /* crash */ +- if (register_netdevice_notifier(&clip_dev_notifier)) +- printk(KERN_ERR "register_netdevice_notifier failed\n"); +- if (register_inetaddr_notifier(&clip_inet_notifier)) +- printk(KERN_ERR "register_inetaddr_notifier failed\n"); ++ rtnl_unlock(); + return 0; + } + +@@ -992,6 +999,8 @@ + + clip_tbl_hook = &clip_tbl; + register_atm_ioctl(&clip_ioctl_ops); ++ register_netdevice_notifier(&clip_dev_notifier); ++ register_inetaddr_notifier(&clip_inet_notifier); + + #ifdef CONFIG_PROC_FS + { +@@ -1012,6 +1021,9 @@ + + remove_proc_entry("arp", atm_proc_root); + ++ unregister_inetaddr_notifier(&clip_inet_notifier); ++ unregister_netdevice_notifier(&clip_dev_notifier); ++ + deregister_atm_ioctl(&clip_ioctl_ops); + + /* First, stop the idle timer, so it stops banging +diff -Naur linux-2.6.16/net/bridge/br_netfilter.c linux-2.6.16.16/net/bridge/br_netfilter.c +--- linux-2.6.16/net/bridge/br_netfilter.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/bridge/br_netfilter.c 2006-05-11 04:56:24.000000000 +0300 +@@ -739,6 +739,15 @@ + return NF_STOLEN; + } + ++static int br_nf_dev_queue_xmit(struct sk_buff *skb) ++{ ++ if (skb->protocol == htons(ETH_P_IP) && ++ skb->len > skb->dev->mtu && ++ !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) ++ return ip_fragment(skb, br_dev_queue_push_xmit); ++ else ++ return br_dev_queue_push_xmit(skb); ++} + + /* PF_BRIDGE/POST_ROUTING ********************************************/ + static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, +@@ -798,7 +807,7 @@ + realoutdev = nf_bridge->netoutdev; + #endif + NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev, +- br_dev_queue_push_xmit); ++ br_nf_dev_queue_xmit); + + return NF_STOLEN; + +@@ -843,7 +852,7 @@ + if ((out->hard_start_xmit == br_dev_xmit && + okfn != br_nf_forward_finish && + okfn != br_nf_local_out_finish && +- okfn != br_dev_queue_push_xmit) ++ okfn != br_nf_dev_queue_xmit) + #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + || ((out->priv_flags & IFF_802_1Q_VLAN) && + VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) +diff -Naur linux-2.6.16/net/core/dev.c linux-2.6.16.16/net/core/dev.c +--- linux-2.6.16/net/core/dev.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/core/dev.c 2006-05-11 04:56:24.000000000 +0300 +@@ -2932,11 +2932,11 @@ + + switch(dev->reg_state) { + case NETREG_REGISTERING: ++ dev->reg_state = NETREG_REGISTERED; + err = netdev_register_sysfs(dev); + if (err) + printk(KERN_ERR "%s: failed sysfs registration (%d)\n", + dev->name, err); +- dev->reg_state = NETREG_REGISTERED; + break; + + case NETREG_UNREGISTERING: +diff -Naur linux-2.6.16/net/core/sock.c linux-2.6.16.16/net/core/sock.c +--- linux-2.6.16/net/core/sock.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/core/sock.c 2006-05-11 04:56:24.000000000 +0300 +@@ -404,8 +404,9 @@ + if (!valbool) { + sk->sk_bound_dev_if = 0; + } else { +- if (optlen > IFNAMSIZ) +- optlen = IFNAMSIZ; ++ if (optlen > IFNAMSIZ - 1) ++ optlen = IFNAMSIZ - 1; ++ memset(devname, 0, sizeof(devname)); + if (copy_from_user(devname, optval, optlen)) { + ret = -EFAULT; + break; +diff -Naur linux-2.6.16/net/ipv4/fib_trie.c linux-2.6.16.16/net/ipv4/fib_trie.c +--- linux-2.6.16/net/ipv4/fib_trie.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/fib_trie.c 2006-05-11 04:56:24.000000000 +0300 +@@ -314,11 +314,6 @@ + kfree(container_of(head, struct leaf, rcu)); + } + +-static inline void free_leaf(struct leaf *leaf) +-{ +- call_rcu(&leaf->rcu, __leaf_free_rcu); +-} +- + static void __leaf_info_free_rcu(struct rcu_head *head) + { + kfree(container_of(head, struct leaf_info, rcu)); +@@ -357,7 +352,12 @@ + + static inline void tnode_free(struct tnode *tn) + { +- call_rcu(&tn->rcu, __tnode_free_rcu); ++ if(IS_LEAF(tn)) { ++ struct leaf *l = (struct leaf *) tn; ++ call_rcu_bh(&l->rcu, __leaf_free_rcu); ++ } ++ else ++ call_rcu(&tn->rcu, __tnode_free_rcu); + } + + static struct leaf *leaf_new(void) +diff -Naur linux-2.6.16/net/ipv4/ip_output.c linux-2.6.16.16/net/ipv4/ip_output.c +--- linux-2.6.16/net/ipv4/ip_output.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/ip_output.c 2006-05-11 04:56:24.000000000 +0300 +@@ -86,8 +86,6 @@ + + int sysctl_ip_default_ttl = IPDEFTTL; + +-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); +- + /* Generate a checksum for an outgoing IP datagram. */ + __inline__ void ip_send_check(struct iphdr *iph) + { +@@ -421,7 +419,7 @@ + * single device frame, and queue such a frame for sending. + */ + +-static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) ++int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) + { + struct iphdr *iph; + int raw = 0; +@@ -673,6 +671,8 @@ + return err; + } + ++EXPORT_SYMBOL(ip_fragment); ++ + int + ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) + { +@@ -1249,11 +1249,7 @@ + iph->tos = inet->tos; + iph->tot_len = htons(skb->len); + iph->frag_off = df; +- if (!df) { +- __ip_select_ident(iph, &rt->u.dst, 0); +- } else { +- iph->id = htons(inet->id++); +- } ++ ip_select_ident(iph, &rt->u.dst, sk); + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + iph->saddr = rt->rt_src; +diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c +--- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1619,7 +1619,7 @@ + printk("ctnetlink: unregistering from nfnetlink.\n"); + + #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS +- ip_conntrack_unregister_notifier(&ctnl_notifier_exp); ++ ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); + ip_conntrack_unregister_notifier(&ctnl_notifier); + #endif + +diff -Naur linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +--- linux-2.6.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300 +@@ -235,12 +235,15 @@ + flag = 1; + } + +- /* Cookie Ack/Echo chunks not the first OR +- Init / Init Ack / Shutdown compl chunks not the only chunks */ +- if ((sch->type == SCTP_CID_COOKIE_ACK ++ /* ++ * Cookie Ack/Echo chunks not the first OR ++ * Init / Init Ack / Shutdown compl chunks not the only chunks ++ * OR zero-length. ++ */ ++ if (((sch->type == SCTP_CID_COOKIE_ACK + || sch->type == SCTP_CID_COOKIE_ECHO + || flag) +- && count !=0 ) { ++ && count !=0) || !sch->length) { + DEBUGP("Basic checks failed\n"); + return 1; + } +diff -Naur linux-2.6.16/net/ipv4/route.c linux-2.6.16.16/net/ipv4/route.c +--- linux-2.6.16/net/ipv4/route.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/route.c 2006-05-11 04:56:24.000000000 +0300 +@@ -2750,7 +2750,10 @@ + /* Reserve room for dummy headers, this skb can pass + through good chunk of routing engine. + */ +- skb->mac.raw = skb->data; ++ skb->mac.raw = skb->nh.raw = skb->data; ++ ++ /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ ++ skb->nh.iph->protocol = IPPROTO_ICMP; + skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); + + if (rta[RTA_SRC - 1]) +diff -Naur linux-2.6.16/net/ipv4/tcp_output.c linux-2.6.16.16/net/ipv4/tcp_output.c +--- linux-2.6.16/net/ipv4/tcp_output.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv4/tcp_output.c 2006-05-11 04:56:24.000000000 +0300 +@@ -537,7 +537,9 @@ + buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); + if (buff == NULL) + return -ENOMEM; /* We'll just try again later. */ +- sk_charge_skb(sk, buff); ++ ++ buff->truesize = skb->len - len; ++ skb->truesize -= buff->truesize; + + /* Correct the sequence numbers. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; +diff -Naur linux-2.6.16/net/ipv6/exthdrs.c linux-2.6.16.16/net/ipv6/exthdrs.c +--- linux-2.6.16/net/ipv6/exthdrs.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv6/exthdrs.c 2006-05-11 04:56:24.000000000 +0300 +@@ -489,6 +489,18 @@ + { + struct inet6_skb_parm *opt = IP6CB(skb); + ++ /* ++ * skb->nh.raw is equal to skb->data, and ++ * skb->h.raw - skb->nh.raw is always equal to ++ * sizeof(struct ipv6hdr) by definition of ++ * hop-by-hop options. ++ */ ++ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || ++ !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { ++ kfree_skb(skb); ++ return -1; ++ } ++ + opt->hop = sizeof(struct ipv6hdr); + if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { + skb->h.raw += (skb->h.raw[1]+1)<<3; +diff -Naur linux-2.6.16/net/ipv6/xfrm6_policy.c linux-2.6.16.16/net/ipv6/xfrm6_policy.c +--- linux-2.6.16/net/ipv6/xfrm6_policy.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/ipv6/xfrm6_policy.c 2006-05-11 04:56:24.000000000 +0300 +@@ -191,16 +191,18 @@ + static inline void + _decode_session6(struct sk_buff *skb, struct flowi *fl) + { +- u16 offset = sizeof(struct ipv6hdr); ++ u16 offset = skb->h.raw - skb->nh.raw; + struct ipv6hdr *hdr = skb->nh.ipv6h; +- struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); +- u8 nexthdr = skb->nh.ipv6h->nexthdr; ++ struct ipv6_opt_hdr *exthdr; ++ u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; + + memset(fl, 0, sizeof(struct flowi)); + ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); + ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); + + while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { ++ exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); ++ + switch (nexthdr) { + case NEXTHDR_ROUTING: + case NEXTHDR_HOP: +diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_netlink.c linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c +--- linux-2.6.16/net/netfilter/nf_conntrack_netlink.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/netfilter/nf_conntrack_netlink.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1641,7 +1641,7 @@ + printk("ctnetlink: unregistering from nfnetlink.\n"); + + #ifdef CONFIG_NF_CONNTRACK_EVENTS +- nf_conntrack_unregister_notifier(&ctnl_notifier_exp); ++ nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); + nf_conntrack_unregister_notifier(&ctnl_notifier); + #endif + +diff -Naur linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c +--- linux-2.6.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/netfilter/nf_conntrack_proto_sctp.c 2006-05-11 04:56:24.000000000 +0300 +@@ -240,12 +240,15 @@ + flag = 1; + } + +- /* Cookie Ack/Echo chunks not the first OR +- Init / Init Ack / Shutdown compl chunks not the only chunks */ +- if ((sch->type == SCTP_CID_COOKIE_ACK ++ /* ++ * Cookie Ack/Echo chunks not the first OR ++ * Init / Init Ack / Shutdown compl chunks not the only chunks ++ * OR zero-length. ++ */ ++ if (((sch->type == SCTP_CID_COOKIE_ACK + || sch->type == SCTP_CID_COOKIE_ECHO + || flag) +- && count !=0 ) { ++ && count !=0) || !sch->length) { + DEBUGP("Basic checks failed\n"); + return 1; + } +diff -Naur linux-2.6.16/net/sctp/inqueue.c linux-2.6.16.16/net/sctp/inqueue.c +--- linux-2.6.16/net/sctp/inqueue.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/sctp/inqueue.c 2006-05-11 04:56:24.000000000 +0300 +@@ -149,6 +149,7 @@ + /* This is the first chunk in the packet. */ + chunk->singleton = 1; + ch = (sctp_chunkhdr_t *) chunk->skb->data; ++ chunk->data_accepted = 0; + } + + chunk->chunk_hdr = ch; +diff -Naur linux-2.6.16/net/sctp/sm_statefuns.c linux-2.6.16.16/net/sctp/sm_statefuns.c +--- linux-2.6.16/net/sctp/sm_statefuns.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/sctp/sm_statefuns.c 2006-05-11 04:56:24.000000000 +0300 +@@ -636,8 +636,9 @@ + */ + chunk->subh.cookie_hdr = + (struct sctp_signed_cookie *)chunk->skb->data; +- skb_pull(chunk->skb, +- ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); ++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - ++ sizeof(sctp_chunkhdr_t))) ++ goto nomem; + + /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint + * "Z" will reply with a COOKIE ACK chunk after building a TCB +@@ -965,7 +966,8 @@ + */ + chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; + paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); +- skb_pull(chunk->skb, paylen); ++ if (!pskb_pull(chunk->skb, paylen)) ++ goto nomem; + + reply = sctp_make_heartbeat_ack(asoc, chunk, + chunk->subh.hb_hdr, paylen); +@@ -1860,8 +1862,9 @@ + * are in good shape. + */ + chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; +- skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - +- sizeof(sctp_chunkhdr_t)); ++ if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - ++ sizeof(sctp_chunkhdr_t))) ++ goto nomem; + + /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie + * of a duplicate COOKIE ECHO match the Verification Tags of the +@@ -5151,7 +5154,9 @@ + int tmp; + __u32 tsn; + int account_value; ++ struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; + struct sock *sk = asoc->base.sk; ++ int rcvbuf_over = 0; + + data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data; + skb_pull(chunk->skb, sizeof(sctp_datahdr_t)); +@@ -5162,10 +5167,16 @@ + /* ASSERT: Now skb->data is really the user data. */ + + /* +- * if we are established, and we have used up our receive +- * buffer memory, drop the frame ++ * If we are established, and we have used up our receive buffer ++ * memory, think about droping the frame. ++ * Note that we have an opportunity to improve performance here. ++ * If we accept one chunk from an skbuff, we have to keep all the ++ * memory of that skbuff around until the chunk is read into user ++ * space. Therefore, once we accept 1 chunk we may as well accept all ++ * remaining chunks in the skbuff. The data_accepted flag helps us do ++ * that. + */ +- if (asoc->state == SCTP_STATE_ESTABLISHED) { ++ if ((asoc->state == SCTP_STATE_ESTABLISHED) && (!chunk->data_accepted)) { + /* + * If the receive buffer policy is 1, then each + * association can allocate up to sk_rcvbuf bytes +@@ -5176,9 +5187,25 @@ + account_value = atomic_read(&asoc->rmem_alloc); + else + account_value = atomic_read(&sk->sk_rmem_alloc); +- +- if (account_value > sk->sk_rcvbuf) +- return SCTP_IERROR_IGNORE_TSN; ++ if (account_value > sk->sk_rcvbuf) { ++ /* ++ * We need to make forward progress, even when we are ++ * under memory pressure, so we always allow the ++ * next tsn after the ctsn ack point to be accepted. ++ * This lets us avoid deadlocks in which we have to ++ * drop frames that would otherwise let us drain the ++ * receive queue. ++ */ ++ if ((sctp_tsnmap_get_ctsn(map) + 1) != tsn) ++ return SCTP_IERROR_IGNORE_TSN; ++ ++ /* ++ * We're going to accept the frame but we should renege ++ * to make space for it. This will send us down that ++ * path later in this function. ++ */ ++ rcvbuf_over = 1; ++ } + } + + /* Process ECN based congestion. +@@ -5226,6 +5253,7 @@ + datalen -= sizeof(sctp_data_chunk_t); + + deliver = SCTP_CMD_CHUNK_ULP; ++ chunk->data_accepted = 1; + + /* Think about partial delivery. */ + if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { +@@ -5242,7 +5270,8 @@ + * large spill over. + */ + if (!asoc->rwnd || asoc->rwnd_over || +- (datalen > asoc->rwnd + asoc->frag_point)) { ++ (datalen > asoc->rwnd + asoc->frag_point) || ++ rcvbuf_over) { + + /* If this is the next TSN, consider reneging to make + * room. Note: Playing nice with a confused sender. A +@@ -5250,8 +5279,8 @@ + * space and in the future we may want to detect and + * do more drastic reneging. + */ +- if (sctp_tsnmap_has_gap(&asoc->peer.tsn_map) && +- (sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1) == tsn) { ++ if (sctp_tsnmap_has_gap(map) && ++ (sctp_tsnmap_get_ctsn(map) + 1) == tsn) { + SCTP_DEBUG_PRINTK("Reneging for tsn:%u\n", tsn); + deliver = SCTP_CMD_RENEGE; + } else { +diff -Naur linux-2.6.16/net/sctp/sm_statetable.c linux-2.6.16.16/net/sctp/sm_statetable.c +--- linux-2.6.16/net/sctp/sm_statetable.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/sctp/sm_statetable.c 2006-05-11 04:56:24.000000000 +0300 +@@ -366,9 +366,9 @@ + /* SCTP_STATE_EMPTY */ \ + {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ + /* SCTP_STATE_CLOSED */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_COOKIE_WAIT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_COOKIE_ECHOED */ \ + {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ + /* SCTP_STATE_ESTABLISHED */ \ +@@ -380,7 +380,7 @@ + /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ + {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ + /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + } /* TYPE_SCTP_ECN_ECNE */ + + #define TYPE_SCTP_ECN_CWR { \ +@@ -401,7 +401,7 @@ + /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ + } /* TYPE_SCTP_ECN_CWR */ + + #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ +@@ -647,7 +647,7 @@ + /* SCTP_STATE_EMPTY */ \ + {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + /* SCTP_STATE_CLOSED */ \ +- {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ ++ {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ + /* SCTP_STATE_COOKIE_WAIT */ \ + {.fn = sctp_sf_do_prm_requestheartbeat, \ + .name = "sctp_sf_do_prm_requestheartbeat"}, \ +diff -Naur linux-2.6.16/net/sctp/ulpqueue.c linux-2.6.16.16/net/sctp/ulpqueue.c +--- linux-2.6.16/net/sctp/ulpqueue.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/net/sctp/ulpqueue.c 2006-05-11 04:56:24.000000000 +0300 +@@ -279,6 +279,7 @@ + static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) + { + struct sk_buff *pos; ++ struct sk_buff *new = NULL; + struct sctp_ulpevent *event; + struct sk_buff *pnext, *last; + struct sk_buff *list = skb_shinfo(f_frag)->frag_list; +@@ -297,11 +298,33 @@ + */ + if (last) + last->next = pos; +- else +- skb_shinfo(f_frag)->frag_list = pos; ++ else { ++ if (skb_cloned(f_frag)) { ++ /* This is a cloned skb, we can't just modify ++ * the frag_list. We need a new skb to do that. ++ * Instead of calling skb_unshare(), we'll do it ++ * ourselves since we need to delay the free. ++ */ ++ new = skb_copy(f_frag, GFP_ATOMIC); ++ if (!new) ++ return NULL; /* try again later */ ++ ++ new->sk = f_frag->sk; ++ ++ skb_shinfo(new)->frag_list = pos; ++ } else ++ skb_shinfo(f_frag)->frag_list = pos; ++ } + + /* Remove the first fragment from the reassembly queue. */ + __skb_unlink(f_frag, queue); ++ ++ /* if we did unshare, then free the old skb and re-assign */ ++ if (new) { ++ kfree_skb(f_frag); ++ f_frag = new; ++ } ++ + while (pos) { + + pnext = pos->next; +diff -Naur linux-2.6.16/security/keys/key.c linux-2.6.16.16/security/keys/key.c +--- linux-2.6.16/security/keys/key.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/security/keys/key.c 2006-05-11 04:56:24.000000000 +0300 +@@ -785,6 +785,10 @@ + + key_check(keyring); + ++ key_ref = ERR_PTR(-ENOTDIR); ++ if (keyring->type != &key_type_keyring) ++ goto error_2; ++ + down_write(&keyring->sem); + + /* if we're going to allocate a new key, we're going to have +diff -Naur linux-2.6.16/security/keys/keyring.c linux-2.6.16.16/security/keys/keyring.c +--- linux-2.6.16/security/keys/keyring.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/security/keys/keyring.c 2006-05-11 04:56:24.000000000 +0300 +@@ -437,6 +437,7 @@ + /* + * search the given keyring only (no recursion) + * - keyring must be locked by caller ++ * - caller must guarantee that the keyring is a keyring + */ + key_ref_t __keyring_search_one(key_ref_t keyring_ref, + const struct key_type *ktype, +diff -Naur linux-2.6.16/security/selinux/ss/mls.c linux-2.6.16.16/security/selinux/ss/mls.c +--- linux-2.6.16/security/selinux/ss/mls.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/security/selinux/ss/mls.c 2006-05-11 04:56:24.000000000 +0300 +@@ -264,7 +264,7 @@ + + if (!selinux_mls_enabled) { + if (def_sid != SECSID_NULL && oldc) +- *scontext += strlen(*scontext); ++ *scontext += strlen(*scontext)+1; + return 0; + } + +diff -Naur linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c +--- linux-2.6.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/sound/isa/opti9xx/opti92x-ad1848.c 2006-05-11 04:56:24.000000000 +0300 +@@ -2088,9 +2088,11 @@ + int error; + struct platform_device *device; + ++#ifdef CONFIG_PNP + pnp_register_card_driver(&opti9xx_pnpc_driver); + if (snd_opti9xx_pnp_is_probed) + return 0; ++#endif + if (! is_isapnp_selected()) { + error = platform_driver_register(&snd_opti9xx_driver); + if (error < 0) +@@ -2102,7 +2104,9 @@ + } + platform_driver_unregister(&snd_opti9xx_driver); + } ++#ifdef CONFIG_PNP + pnp_unregister_card_driver(&opti9xx_pnpc_driver); ++#endif + #ifdef MODULE + printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); + #endif +@@ -2115,7 +2119,9 @@ + platform_device_unregister(snd_opti9xx_platform_device); + platform_driver_unregister(&snd_opti9xx_driver); + } ++#ifdef CONFIG_PNP + pnp_unregister_card_driver(&opti9xx_pnpc_driver); ++#endif + } + + module_init(alsa_card_opti9xx_init) +diff -Naur linux-2.6.16/sound/oss/dmasound/tas_common.c linux-2.6.16.16/sound/oss/dmasound/tas_common.c +--- linux-2.6.16/sound/oss/dmasound/tas_common.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/sound/oss/dmasound/tas_common.c 2006-05-11 04:56:24.000000000 +0300 +@@ -195,8 +195,8 @@ + + printk(KERN_INFO "tas driver [%s])\n", driver_name); + +-#ifndef CONFIG_I2C_KEYWEST +- request_module("i2c-keywest"); ++#ifndef CONFIG_I2C_POWERMAC ++ request_module("i2c-powermac"); + #endif + tas_node = find_devices("deq"); + if (tas_node == NULL) +diff -Naur linux-2.6.16/sound/pci/hda/patch_realtek.c linux-2.6.16.16/sound/pci/hda/patch_realtek.c +--- linux-2.6.16/sound/pci/hda/patch_realtek.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/sound/pci/hda/patch_realtek.c 2006-05-11 04:56:24.000000000 +0300 +@@ -2948,6 +2948,8 @@ + { .modelname = "basic", .config = ALC260_BASIC }, + { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, + .config = ALC260_BASIC }, /* Sony VAIO */ ++ { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729, ++ .config = ALC260_BASIC }, /* CTL Travel Master U553W */ + { .modelname = "hp", .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP }, + { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP }, +diff -Naur linux-2.6.16/sound/ppc/daca.c linux-2.6.16.16/sound/ppc/daca.c +--- linux-2.6.16/sound/ppc/daca.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/sound/ppc/daca.c 2006-05-11 04:56:24.000000000 +0300 +@@ -256,7 +256,7 @@ + + #ifdef CONFIG_KMOD + if (current->fs->root) +- request_module("i2c-keywest"); ++ request_module("i2c-powermac"); + #endif /* CONFIG_KMOD */ + + mix = kmalloc(sizeof(*mix), GFP_KERNEL); +diff -Naur linux-2.6.16/sound/ppc/tumbler.c linux-2.6.16.16/sound/ppc/tumbler.c +--- linux-2.6.16/sound/ppc/tumbler.c 2006-03-20 07:53:29.000000000 +0200 ++++ linux-2.6.16.16/sound/ppc/tumbler.c 2006-05-11 04:56:24.000000000 +0300 +@@ -1314,7 +1314,7 @@ + + #ifdef CONFIG_KMOD + if (current->fs->root) +- request_module("i2c-keywest"); ++ request_module("i2c-powermac"); + #endif /* CONFIG_KMOD */ + + mix = kmalloc(sizeof(*mix), GFP_KERNEL); diff --git a/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch new file mode 100644 index 0000000000..98b4365f98 --- /dev/null +++ b/packages/linux/linux-h6300-omap1-2.6.16.16/linux-h6300-omap2-2.6.16.16.patch @@ -0,0 +1,3736 @@ +diff -Naur linux-2.6.16.16/arch/arm/Kconfig h6300_dev/arch/arm/Kconfig +--- linux-2.6.16.16/arch/arm/Kconfig 2006-05-17 21:41:27.000000000 +0300 ++++ h6300_dev/arch/arm/Kconfig 2006-04-02 00:23:01.000000000 +0300 +@@ -811,6 +811,8 @@ + + source "drivers/video/Kconfig" + ++source "drivers/telephony/Kconfig" ++ + source "sound/Kconfig" + + source "drivers/usb/Kconfig" +diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c h6300_dev/arch/arm/mach-omap1/board-h6300.c +--- linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/arch/arm/mach-omap1/board-h6300.c 2006-04-24 20:53:29.000000000 +0300 +@@ -0,0 +1,424 @@ ++/* ++ * Modified from board-h6300.c ++ * ++ * Code for generic OMAP board. Should work on many OMAP systems where ++ * the device drivers take care of all the necessary hardware initialization. ++ * Do not put any board specific code to this file; create a new machine ++ * type if you need custom low-level initializations. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/input.h> ++ ++#include <asm/hardware.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++#include <asm/mach/flash.h> ++#include <asm/mach/map.h> ++ ++#include <asm/arch/gpio.h> ++ ++#include <asm/arch/tc.h> ++#include <asm/arch/usb.h> ++#include <asm/arch/keypad.h> ++#include <asm/arch/common.h> ++#include <asm/arch/mcbsp.h> ++#include <asm/arch/omap-alsa.h> ++#include <asm/arch/h6300_uart_info.h> ++ ++#define _h6300_KEY_CALENDAR 67 // xmodmap 75 aka F9 ++#define _H6300_KEY_TELEPHONE 68 // xmodmap 76 aka F10 ++#define _H6300_KEY_HOMEPAGE 87 // xmodmap 87 aka Num_Lock ++#define _H6300_KEY_MAIL 88 // xmodmap 88 aka Scroll_Lock ++ ++/* ++ * Following 5 keypad events are not really sent to userspace. ++ * Instead if the good combination of them is sent, then that is send. ++ * (up, right, down, left, enter) ++ */ ++#define _H6300_JOYPAD_UP_RIGHT 1 // 00001 ++#define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010 ++#define _h6300_JOYPAD_DOWN_LEFT 4 // 00100 ++#define _h6300_JOYPAD_UP_LEFT 8 // 01000 ++#define _H6300_JOYPAD_KEY_OK 16 // 10000 ++ ++static int h6300_keymap[] = { ++ KEY(2, 0, _h6300_KEY_CALENDAR), // address button in the bottom left ++ KEY(2, 3, _H6300_KEY_TELEPHONE), // start call button in the bottom ++ KEY(3, 1, _H6300_KEY_HOMEPAGE), // stop call button in the bottom ++ KEY(3, 4, _H6300_KEY_MAIL), // messaging button in the bottom right ++ ++ KEY(0, 0, KEY_VOLUMEUP), // volume up button in the right side ++ KEY(0, 1, KEY_VOLUMEDOWN), // volume down button in the right side ++ KEY(3, 2, KEY_RECORD), // record button in the left side ++ ++ KEY(1, 0, _h6300_JOYPAD_UP_LEFT), ++ KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT), ++ KEY(1, 2, _H6300_JOYPAD_KEY_OK), ++ KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT), ++ KEY(1, 4, _H6300_JOYPAD_UP_RIGHT), ++ ++ KEY(4, 0, KEY_RIGHT), ++ KEY(4, 1, KEY_DOWN), ++ KEY(4, 2, KEY_LEFT), ++ KEY(4, 3, KEY_UP), ++ KEY(4, 4, KEY_ENTER), ++ ++ 0 ++}; ++ ++/* ++ * Bluetooth - Relies on h6300_bt module, ++ * so make the calls indirectly through pointers. Requires that the ++ * h6300_bt bluetooth module be loaded before any attempt to use ++ * bluetooth (obviously). ++ */ ++ ++static struct h6300_uart_funcs bt_funcs; ++static struct h6300_uart_funcs gsm_funcs; ++ ++static void h6300_bt_configure(struct uart_omap_port *up, int enable) ++{ ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() started\n"); ++ if (bt_funcs.configure != NULL) ++ bt_funcs.configure(up, enable); ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() done\n"); ++} ++ ++static void h6300_bt_set_txrx(struct uart_omap_port *up, int txrx) ++{ ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() started\n"); ++ if (bt_funcs.set_txrx != NULL) ++ { ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx(), bt_funcs.set_txrx != NULL\n"); ++ bt_funcs.set_txrx(up, txrx); ++ } ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() done\n"); ++} ++ ++static int h6300_bt_get_txrx(struct uart_omap_port *up) ++{ ++ int retVal; ++ ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() started\n"); ++ if (bt_funcs.get_txrx != NULL) ++ { ++ retVal = bt_funcs.get_txrx(up); ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal); ++ return retVal; ++ } ++ else ++ { ++ printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() done, returning 0\n"); ++ return 0; ++ } ++} ++ ++static struct platform_omap_serial_funcs h6300_omap_bt_funcs = { ++ .configure = h6300_bt_configure, ++ .set_txrx = h6300_bt_set_txrx, ++ .get_txrx = h6300_bt_get_txrx, ++}; ++ ++struct platform_device btuart_device = { ++ .name = "h6300_bt", ++ .id = 1, ++}; ++EXPORT_SYMBOL(btuart_device); ++ ++static void h6300_gsm_configure(struct uart_omap_port *up, int enable) ++{ ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() started\n"); ++ if (gsm_funcs.configure != NULL) ++ gsm_funcs.configure(up, enable); ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() done\n"); ++} ++ ++static void h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx) ++{ ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() started\n"); ++ if (bt_funcs.set_txrx != NULL) ++ { ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx(), bt_funcs.set_txrx != NULL\n"); ++ gsm_funcs.set_txrx(up, txrx); ++ } ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() done\n"); ++} ++ ++static int h6300_gsm_get_txrx(struct uart_omap_port *up) ++{ ++ int retVal; ++ ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() started\n"); ++ if (bt_funcs.get_txrx != NULL) ++ { ++ retVal = gsm_funcs.get_txrx(up); ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal); ++ return retVal; ++ } ++ else ++ { ++ printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() done, returning 0\n"); ++ return 0; ++ } ++} ++ ++static struct platform_omap_serial_funcs h6300_omap_gsm_funcs = { ++ .configure = h6300_gsm_configure, ++ .set_txrx = h6300_gsm_set_txrx, ++ .get_txrx = h6300_gsm_get_txrx, ++}; ++ ++struct platform_device gsmuart_device = { ++ .name = "h6300_gsm", ++ .id = 1, ++}; ++EXPORT_SYMBOL(gsmuart_device); ++ ++#if 0 ++static struct mtd_partition h6300_partitions[] = { ++ /* bootloader (U-Boot, etc) in first sector */ ++ { ++ .name = "bootloader", ++ .offset = 0, ++ .size = SZ_128K, ++ .mask_flags = MTD_WRITEABLE, /* force read-only */ ++ }, ++ /* bootloader params in the next sector */ ++ { ++ .name = "params", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_128K, ++ .mask_flags = 0, ++ }, ++ /* kernel */ ++ { ++ .name = "kernel", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_2M, ++ .mask_flags = 0 ++ }, ++ /* rest of flash1 is a file system */ ++ { ++ .name = "rootfs", ++ .offset = MTDPART_OFS_APPEND, ++ .size = SZ_16M - SZ_2M - 2 * SZ_128K, ++ .mask_flags = 0 ++ }, ++ /* file system */ ++ { ++ .name = "filesystem", ++ .offset = MTDPART_OFS_APPEND, ++ .size = MTDPART_SIZ_FULL, ++ .mask_flags = 0 ++ } ++}; ++ ++static struct flash_platform_data h6300_flash_data = { ++ .map_name = "cfi_probe", ++ .width = 2, ++ .parts = h6300_partitions, ++ .nr_parts = ARRAY_SIZE(h6300_partitions), ++}; ++ ++static struct resource h6300_flash_resource = { ++ .start = OMAP_CS0_PHYS, ++ .end = OMAP_CS0_PHYS + SZ_32M - 1, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct platform_device h6300_flash_device = { ++ .name = "omapflash", ++ .id = 0, ++ .dev = { ++ .platform_data = &h6300_flash_data, ++ }, ++static struct platform_device h6300_flash_device = { ++ .name = "omapflash", ++ .id = 0, ++ .dev = { ++ .platform_data = &h6300_flash_data, ++ }, ++ .num_resources = 1, ++ .resource = &h6300_flash_resource, ++}; ++#endif ++ ++static struct resource h6300_kp_resources[] = { ++ [0] = { ++ .start = INT_KEYBOARD, ++ .end = INT_KEYBOARD, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct omap_kp_platform_data h6300_kp_data = { ++ .rows = 8, ++ .cols = 8, ++ .keymap = h6300_keymap, ++ .rep = 1, // turns repeat bit on ++}; ++ ++static struct platform_device h6300_kp_device = { ++ .name = "omap-keypad", ++ .id = -1, ++ .dev = { ++ .platform_data = &h6300_kp_data, ++ }, ++ .num_resources = ARRAY_SIZE(h6300_kp_resources), ++ .resource = h6300_kp_resources, ++}; ++ ++static struct resource h6300_wlan_resource[] = { ++ [0] = { ++ .start = OMAP_CS1_PHYS, ++ .end = OMAP_CS1_PHYS + SZ_32M -1, ++ .flags = IORESOURCE_MEM, ++ }, ++ ++ [1] = { ++ .start = OMAP_GPIO_IRQ(11), ++ .end = OMAP_GPIO_IRQ(11), ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device h6300_wlan_device = { ++ .name = "tnetw1100b", ++ .id = 0, ++ .num_resources = 2, ++ .resource = h6300_wlan_resource, ++}; ++ ++static struct omap_mcbsp_reg_cfg mcbsp_regs = { ++ .spcr2 = 0x0000, ++ .spcr1 = 0x0000, ++ .rcr2 = 0x8041, ++ .rcr1 = 0x0040, ++ .xcr2 = 0x00a1, ++ .xcr1 = 0x00a0, ++ .srgr2 = 0xb000, ++ .srgr1 = 0x0000, ++ .pcr0 = 0x0081, ++}; ++ ++static struct omap_alsa_codec_config alsa_config = { ++ .name = "iPAQ h6300 TSC2101", ++ .mcbsp_regs_alsa = &mcbsp_regs, ++ .codec_configure_dev = NULL, //tsc2101_configure, ++ .codec_set_samplerate = NULL, //tsc2101_set_samplerate, ++ .codec_clock_setup = NULL, //tsc2101_clock_setup, ++ .codec_clock_on = NULL, //tsc2101_clock_on, ++ .codec_clock_off = NULL, //tsc2101_clock_off, ++ .get_default_samplerate = NULL, //tsc2101_get_default_samplerate, ++}; ++ ++static struct platform_device h6300_mcbsp1_device = { ++ .name = "omap_alsa_mcbsp", ++ .id = 1, ++ .dev = { ++ .platform_data = &alsa_config, ++ }, ++}; ++ ++static struct platform_device h6300_lcd_device = { ++ .name = "lcd_h6300", ++ .id = -1, ++}; ++ ++static struct platform_device *h6300_devices[] __initdata = { ++ &h6300_lcd_device, ++ &btuart_device, ++ &gsmuart_device, ++ &h6300_kp_device, ++ &h6300_mcbsp1_device, ++ &h6300_wlan_device, ++ //&h6300_flash_device, ++}; ++ ++static void __init h6300_init_irq(void) ++{ ++ omap1_init_common_hw(); ++ omap_init_irq(); ++ omap_gpio_init(); ++ ++ /* this is now done in the drivers/input/touschreen/omap/ts_hx.c*/ ++ //omap_request_gpio(2); ++ //omap_set_gpio_direction(2, 0); ++ //omap_set_gpio_dataout(2, 1); ++} ++ ++/* assume no Mini-AB port */ ++ ++static struct omap_usb_config h6300_usb_config __initdata = { ++ .hmc_mode = 0, ++ .register_dev = 1, ++ .pins[0] = 0, ++}; ++ ++static struct omap_lcd_config h6300_lcd_config __initdata = { ++ .ctrl_name = "internal", ++}; ++ ++static struct omap_mmc_config h6300_mmc_config __initdata = { ++ .mmc [0] = { ++ .enabled = 1, ++ .wire4 = 1, ++ .wp_pin = OMAP_GPIO_IRQ(13), ++ .power_pin = -1, // tps65010 ? ++ .switch_pin = -1, // OMAP_MPUIO(1), // = -1, // ARMIO2? ++ }, ++}; ++ ++static struct omap_uart_config h6300_uart_config __initdata = { ++ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), ++}; ++ ++static struct omap_board_config_kernel h6300_config[] = { ++ { OMAP_TAG_USB, &h6300_usb_config }, ++ { OMAP_TAG_MMC, &h6300_mmc_config }, ++ { OMAP_TAG_UART, &h6300_uart_config }, ++ { OMAP_TAG_LCD, &h6300_lcd_config }, ++}; ++ ++static void __init h6300_init(void) ++{ ++ int ret; ++ ++ ret = platform_add_devices(h6300_devices, ARRAY_SIZE(h6300_devices)); ++ if (ret) ++ { ++ printk(KERN_WARNING "Unable to add h6300 platform devices like bluetooth"); ++ } ++ omap_board_config = h6300_config; ++ omap_board_config_size = ARRAY_SIZE(h6300_config); ++ omap_serial_init(); ++} ++ ++static void __init h6300_map_io(void) ++{ ++ omap1_map_common_io(); ++ ++ btuart_device.dev.platform_data = &h6300_omap_bt_funcs; ++ gsmuart_device.dev.platform_data = &h6300_omap_gsm_funcs; ++} ++ ++MACHINE_START(OMAP_H6300, "HP iPAQ h6300") ++ /* MAINTAINER("Everett Coleman II <gcc80x86@fuzzyneural.net>") */ ++ .phys_io = 0xfff00000, ++ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, ++ .boot_params = 0x10000100, ++ .map_io = h6300_map_io, ++ .init_irq = h6300_init_irq, ++ .init_machine = h6300_init, ++ .timer = &omap_timer, ++MACHINE_END +diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Kconfig h6300_dev/arch/arm/mach-omap1/Kconfig +--- linux-2.6.16.16/arch/arm/mach-omap1/Kconfig 2006-05-17 21:41:27.000000000 +0300 ++++ h6300_dev/arch/arm/mach-omap1/Kconfig 2006-04-02 20:47:24.000000000 +0300 +@@ -26,6 +26,15 @@ + TI OMAP 1510 or 1610 Innovator board support. Say Y here if you + have such a board. + ++config MACH_OMAP_H6300 ++ bool "HP iPAQ h6300 series" ++ depends on ARCH_OMAP1 && ARCH_OMAP15XX ++ select I2C ++ select PCA9535 ++ help ++ HP iPAQ h6315, h6340 and h6365 devices that are based ++ on the OMAP 1510. Say Y here if you have such a device. ++ + config MACH_OMAP_H2 + bool "TI H2 Support" + depends on ARCH_OMAP1 && ARCH_OMAP16XX +diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Makefile h6300_dev/arch/arm/mach-omap1/Makefile +--- linux-2.6.16.16/arch/arm/mach-omap1/Makefile 2006-05-17 21:41:28.000000000 +0300 ++++ h6300_dev/arch/arm/mach-omap1/Makefile 2006-04-02 00:23:01.000000000 +0300 +@@ -23,6 +23,7 @@ + obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o + obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o + obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o ++obj-$(CONFIG_MACH_OMAP_H6300) += board-h6300.o + + ifeq ($(CONFIG_ARCH_OMAP15XX),y) + # Innovator-1510 FPGA +@@ -36,4 +37,3 @@ + led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o + led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o + obj-$(CONFIG_LEDS) += $(led-y) +- +diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/mux.c h6300_dev/arch/arm/mach-omap1/mux.c +--- linux-2.6.16.16/arch/arm/mach-omap1/mux.c 2006-05-17 21:41:28.000000000 +0300 ++++ h6300_dev/arch/arm/mach-omap1/mux.c 2006-02-21 23:54:33.000000000 +0200 +@@ -200,6 +200,13 @@ + MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) + MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) + ++/* OMAP-1510 uWire */ ++MUX_CFG("P15_1510_UWIRE_CS3", 8, 12, 1, NA, 0, 0, NA, 0, 1) ++MUX_CFG("N14_1510_UWIRE_CS0", 8, 9, 1, NA, 0, 0, NA, 0, 1) ++MUX_CFG("V19_1510_UWIRE_SCLK", 8, 6, 0, NA, 0, 0, NA, 0, 1) ++MUX_CFG("W21_1510_UWIRE_SDO", 8, 3, 0, NA, 0, 0, NA, 0, 1) ++MUX_CFG("U18_1510_UWIRE_SDI", 8, 0, 0, 1, 18, 0, NA, 0, 1) ++ + /* OMAP-1610 Flash */ + MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) + MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) +@@ -262,6 +269,7 @@ + MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0) + + /* MCLK Settings */ ++MUX_CFG("R10_1510_MCLK_ON", B, 18, 0, 2, 22, 1, NA, 1, 1) + MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0) + MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0) + MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0) +diff -Naur linux-2.6.16.16/arch/arm/plat-omap/devices.c h6300_dev/arch/arm/plat-omap/devices.c +--- linux-2.6.16.16/arch/arm/plat-omap/devices.c 2006-05-17 21:41:28.000000000 +0300 ++++ h6300_dev/arch/arm/plat-omap/devices.c 2006-05-18 00:59:02.000000000 +0300 +@@ -92,7 +92,7 @@ + + static void omap_init_kp(void) + { +- if (machine_is_omap_h2() || machine_is_omap_h3()) { ++ if (machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) { + omap_cfg_reg(F18_1610_KBC0); + omap_cfg_reg(D20_1610_KBC1); + omap_cfg_reg(D19_1610_KBC2); +diff -Naur linux-2.6.16.16/arch/arm/plat-omap/dma.c h6300_dev/arch/arm/plat-omap/dma.c +--- linux-2.6.16.16/arch/arm/plat-omap/dma.c 2006-05-17 21:41:28.000000000 +0300 ++++ h6300_dev/arch/arm/plat-omap/dma.c 2006-02-06 15:36:21.000000000 +0200 +@@ -30,6 +30,7 @@ + #include <asm/hardware.h> + #include <asm/dma.h> + #include <asm/io.h> ++#include <asm/mach-types.h> + + #include <asm/arch/tc.h> + +@@ -1086,6 +1087,10 @@ + } + + if (omap_dma_in_1510_mode()) { ++ u16 l = omap_readw(OMAP1510_DMA_LCD_CTRL); ++ l &= ~(1 << 6); ++ omap_writew (l, OMAP1510_DMA_LCD_CTRL); ++ + omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U); + omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L); + omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U); +diff -Naur linux-2.6.16.16/arch/arm/tools/mach-types h6300_dev/arch/arm/tools/mach-types +--- linux-2.6.16.16/arch/arm/tools/mach-types 2006-05-11 04:56:24.000000000 +0300 ++++ h6300_dev/arch/arm/tools/mach-types 2006-04-24 20:53:29.000000000 +0300 +@@ -576,7 +576,7 @@ + s3c2460 MACH_S3C2460 S3C2460 560 + pdm MACH_PDM PDM 561 + h4700 MACH_H4700 H4700 562 +-h6300 MACH_H6300 H6300 563 ++omap_h6300 MACH_OMAP_H6300 OMAP_H6300 563 + rz1700 MACH_RZ1700 RZ1700 564 + a716 MACH_A716 A716 565 + estk2440a MACH_ESTK2440A ESTK2440A 566 +diff -Naur linux-2.6.16.16/drivers/bluetooth/Kconfig h6300_dev/drivers/bluetooth/Kconfig +--- linux-2.6.16.16/drivers/bluetooth/Kconfig 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/bluetooth/Kconfig 2006-02-21 23:54:33.000000000 +0200 +@@ -166,6 +166,16 @@ + + Say Y here to compile support for virtual HCI devices into the + kernel or say M to compile it as module (hci_vhci). ++ ++config BT_H6300 ++ tristate "H6300 BRF6100 BT DRIVER" ++ help ++ Bluetooth H6300 BRF6100 driver. ++ This driver provides the firmware loading mechanism for the BRF6100 ++ bt hardware in iPAQ h6300. ++ ++ Say Y here to compile support for BRF6100 BT devices into the ++ kernel or say M to compile it as module (h6300_BT). + + endmenu + +diff -Naur linux-2.6.16.16/drivers/bluetooth/Makefile h6300_dev/drivers/bluetooth/Makefile +--- linux-2.6.16.16/drivers/bluetooth/Makefile 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/bluetooth/Makefile 2006-02-21 23:54:33.000000000 +0200 +@@ -13,6 +13,7 @@ + obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o + obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o + obj-$(CONFIG_BT_HCIBRF6150) += brf6150.o ++obj-$(CONFIG_BT_H6300) += omap/ + + hci_uart-y := hci_ldisc.o + hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o +diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c +--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c 2006-01-23 00:09:23.000000000 +0200 +@@ -0,0 +1,154 @@ ++/* ++ * Bluetooth interface driver for TI BRF6100 on h6300 ++ * ++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi> ++ * Ideas taken from the brf6150 bt driver made by Todd Blumer for the pxa hx4700. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch/gpio.h> ++ ++#include <asm/arch/h6300_uart_info.h> ++#include "h6300_bt_led.h" ++ ++static void ++h6300_bt_configure(struct uart_omap_port *up, int enable) ++{ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() started, enable = %d\n", enable); ++ ++ // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable ); ++ if (enable == 0) { ++ omap_set_gpio_dataout(GPIO_N_BT_RST, 1); // turn off gpio, note 1 == off for negative gpios ++ mdelay(5); ++ h6300_clear_led(INDEX_BT_LED); ++ } ++ else if (enable == 1) { ++ omap_set_gpio_dataout(GPIO_N_BT_RST, 1); // turn on gpio, note 0 == on for negative gpios ++ mdelay(5); ++ } ++ else if (enable == 2) { ++ /* ++ * BRF6150's RTS goes low when firmware is ready ++ * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms ++ */ ++/* ++ int tries = 0; ++ do ++ { ++ mdelay(10); ++ } ++ while ((BTMSR & MSR_CTS) == 0 && tries++ < 50); ++*/ ++ h6300_set_led(INDEX_BT_LED, 16, 16); ++ } ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() done\n"); ++} ++ ++static void ++h6300_bt_set_txrx(struct uart_omap_port *up, int txrx) ++{ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_set_txrx(), txrx = %d done\n", txrx); ++ /* do nothing */ ++} ++ ++static int ++h6300_bt_get_txrx(struct uart_omap_port *up) ++{ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_get_txrx() done\n"); ++ /* do nothing */ ++ return 0; ++} ++ ++static int ++h6300_bt_probe(struct platform_device *pdev) ++{ ++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data; ++ ++ omap_request_gpio(GPIO_BT_PWR_EN); // ask bt_power_en gpio, remember to release in remove_function ++ omap_set_gpio_direction(GPIO_BT_PWR_EN, 1); // set gpio direction to be output ++ omap_set_gpio_dataout(GPIO_BT_PWR_EN, 1); // turn on gpio ++ ++ mdelay(200); ++ ++ omap_request_gpio(GPIO_N_BT_RST); // ask bt_reset gpio, remember to release in remove_function ++ omap_set_gpio_direction(GPIO_N_BT_RST, 1); // set gpio direction to be output ++ omap_set_gpio_dataout(GPIO_N_BT_RST, 0); // turn on gpio, note 0 == on for negative gpios ++ ++ /* configure bluetooth UART */ ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD); ++ ++ funcs->configure = h6300_bt_configure; ++ funcs->set_txrx = h6300_bt_set_txrx; ++ funcs->get_txrx = h6300_bt_get_txrx; ++ ++ /* Make sure the LED is off */ ++ h6300_clear_led(INDEX_BT_LED); ++ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_probe() done\n"); ++ ++ return 0; ++} ++ ++static int ++h6300_bt_remove(struct platform_device *pdev) ++{ ++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data; ++ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_remove() started\n"); ++ ++ omap_free_gpio(GPIO_BT_PWR_EN); ++ omap_free_gpio(GPIO_N_BT_RST); ++ ++ funcs->configure = NULL; ++ funcs->set_txrx = NULL; ++ funcs->get_txrx = NULL; ++ ++ /* Make sure the LED is off */ ++ h6300_clear_led(INDEX_BT_LED); ++ ++ printk(KERN_NOTICE "h6300_bt_brf6100.c, h6300_bt_remove() done\n"); ++ ++ return 0; ++} ++ ++static struct platform_driver bt_driver = { ++ .probe = h6300_bt_probe, ++ .remove = h6300_bt_remove, ++ .driver = { ++ .name = "h6300_bt", ++ }, ++}; ++ ++static int __init ++h6300_bt_init(void) ++{ ++ printk(KERN_NOTICE "h6300 Bluetooth Driver init()\n"); ++ return platform_driver_register(&bt_driver); ++} ++ ++static void __exit ++h6300_bt_exit(void) ++{ ++ printk(KERN_NOTICE "h6300 Bluetooth Driver exit()\n"); ++ platform_driver_unregister(&bt_driver); ++} ++ ++module_init(h6300_bt_init); ++module_exit(h6300_bt_exit); ++ ++MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>"); ++MODULE_DESCRIPTION("iPAQ h6300 BRF6100 Bluetooth driver."); ++MODULE_LICENSE("GPL"); ++ +diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c +--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,41 @@ ++/* ++ * Bluetooth interface driver helper for controlling bluetooth leds available in iPAQ h6300. ++ * ++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi> ++ * Ideas from the brf6150 bt driver made by Todd Blumer for the pxa hx4700. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch/gpio.h> ++ ++/* ++ * Low level access for disabling h6300 bt led. ++ * ++ * TODO: implement for h6300 ++ */ ++void h6300_clear_led(int led_num) ++{ ++ printk(KERN_NOTICE "h6300_bt_led.c h6300_clear_led() done\n"); ++ //hx4700_set_led(led_num, 0, 16); ++} ++EXPORT_SYMBOL(h6300_clear_led); ++ ++/* ++ * Low level access for setting up the bt led. ++ * ++ * TODO: implement for h6300 ++ */ ++void h6300_set_led(int led_num, int duty_time, int cycle_time) ++{ ++ printk(KERN_NOTICE "h6300_bt_led.c h6300_set_led() done\n"); ++} ++EXPORT_SYMBOL(h6300_set_led); +diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h +--- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,9 @@ ++#ifndef H6300_BT_LED_H_ ++#define H6300_BT_LED_H_ ++ ++#define INDEX_BT_LED 2 ++ ++void h6300_clear_led(int led_num); ++void h6300_set_led(int led_num, int duty_time, int cycle_time); ++ ++#endif /*H6300_BT_LED_H_*/ +diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/Makefile h6300_dev/drivers/bluetooth/omap/Makefile +--- linux-2.6.16.16/drivers/bluetooth/omap/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/bluetooth/omap/Makefile 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,6 @@ ++# ++# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers. ++# ++ ++h6300_bt-objs := h6300_bt_led.o h6300_bt_brf6100.o ++obj-$(CONFIG_BT_H6300) += h6300_bt.o +diff -Naur linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c h6300_dev/drivers/i2c/busses/i2c-omap.c +--- linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/i2c/busses/i2c-omap.c 2006-04-02 00:23:01.000000000 +0300 +@@ -163,17 +163,22 @@ + + static int omap_i2c_get_clocks(struct omap_i2c_dev *dev) + { +- if (cpu_is_omap16xx() || cpu_is_omap24xx()) { ++ if (cpu_is_omap24xx()) { + dev->iclk = clk_get(dev->dev, "i2c_ick"); +- if (IS_ERR(dev->iclk)) ++ if (IS_ERR(dev->iclk)) { + return -ENODEV; ++ } ++ dev->fclk = clk_get(dev->dev, "i2c_fck"); ++ if (IS_ERR(dev->fclk)) { ++ clk_put(dev->fclk); ++ return -ENODEV; ++ } + } + +- dev->fclk = clk_get(dev->dev, "i2c_fck"); +- if (IS_ERR(dev->fclk)) { +- if (dev->iclk != NULL) +- clk_put(dev->iclk); +- return -ENODEV; ++ if (cpu_class_is_omap1()) { ++ dev->fclk = clk_get(dev->dev, "i2c_fck"); ++ if (IS_ERR(dev->fclk)) ++ return -ENODEV; + } + + return 0; +diff -Naur linux-2.6.16.16/drivers/i2c/chips/Kconfig h6300_dev/drivers/i2c/chips/Kconfig +--- linux-2.6.16.16/drivers/i2c/chips/Kconfig 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/i2c/chips/Kconfig 2006-04-24 20:53:29.000000000 +0300 +@@ -46,6 +46,16 @@ + This driver can also be built as a module. If so, the module + will be called pcf8574. + ++config PCA9535 ++ tristate "Philips PCA9535 16-bit I/O port" ++ depends on I2C ++ help ++ If you say yes here you get support for the Philips PCA9535 ++ 16-bit I/O port. ++ ++ This driver can also be built as a module. If so, the module ++ will be called pca9535. ++ + config SENSORS_PCA9539 + tristate "Philips PCA9539 16-bit I/O port" + depends on I2C && EXPERIMENTAL +diff -Naur linux-2.6.16.16/drivers/i2c/chips/Makefile h6300_dev/drivers/i2c/chips/Makefile +--- linux-2.6.16.16/drivers/i2c/chips/Makefile 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/i2c/chips/Makefile 2006-04-24 20:53:29.000000000 +0300 +@@ -7,6 +7,7 @@ + obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o + obj-$(CONFIG_SENSORS_MAX6875) += max6875.o + obj-$(CONFIG_SENSORS_M41T00) += m41t00.o ++obj-$(CONFIG_PCA9535) += pca9535.o + obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o + obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o + obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o +diff -Naur linux-2.6.16.16/drivers/i2c/chips/pca9535.c h6300_dev/drivers/i2c/chips/pca9535.c +--- linux-2.6.16.16/drivers/i2c/chips/pca9535.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/i2c/chips/pca9535.c 2006-04-24 20:53:29.000000000 +0300 +@@ -0,0 +1,412 @@ ++/* ++ Driver for Philips PCA9535 16-bit low power I/O port with interrupt ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ Copyright (C) 2005 Husam Senussi ++ Framework based on Pawel Kolodziejski's pca9535 driver in ++ handheld.org's 2.6.13 kernel. Driver updated by Mika Laitio. ++*/ ++ ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/i2c.h> ++#include <linux/hwmon-sysfs.h> ++#include <linux/hwmon.h> ++#include <linux/err.h> ++ ++#include <asm/arch/pca9535.h> ++#include <linux/delay.h> ++ ++#include <linux/interrupt.h> ++#include <asm/mach-types.h> ++#include <asm/irq.h> ++#include <asm/mach/arch.h> ++#include <asm/hardware.h> ++ ++EXPORT_SYMBOL(pca9535_gpio_read); ++EXPORT_SYMBOL(pca9535_gpio_write); ++EXPORT_SYMBOL(pca9535_gpio_direction); ++ ++static int pca9535_attach_adapter(struct i2c_adapter *adapter); ++static int pca9535_detach_client(struct i2c_client *client); ++static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one); ++static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr); ++static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 param); ++ ++enum pca9535_cmd ++{ ++ PCA9535_INPUT_0 = 0, ++ PCA9535_INPUT_1 = 1, ++ PCA9535_OUTPUT_0 = 2, ++ PCA9535_OUTPUT_1 = 3, ++ PCA9535_INVERT_0 = 4, ++ PCA9535_INVERT_1 = 5, ++ PCA9535_DIRECTION_0 = 6, ++ PCA9535_DIRECTION_1 = 7, ++}; ++ ++struct pca9535_data { ++ struct semaphore lock; ++ struct i2c_client client; ++}; ++ ++static struct i2c_driver pca9535_driver = { ++ .driver = { ++ .name = "pca9535", ++ }, ++ .attach_adapter = pca9535_attach_adapter, ++ .detach_client = pca9535_detach_client, ++}; ++ ++static struct i2c_client *pca9535_i2c_client = NULL; ++static struct pca9535_data pca9535_inited; ++ ++static unsigned short normal_i2c[] = { 0x20, I2C_CLIENT_END }; ++ ++#define DRIVER_VERSION "20 OCT 2005" ++#define DRIVER_NAME "PCA9535" ++ ++/* ++ * sysfs callback function. ++ */ ++static ssize_t pca9535_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct sensor_device_attribute *psa = to_sensor_dev_attr(attr); ++ struct i2c_client *client = to_i2c_client(dev); ++ return sprintf(buf, "%02X\n", (pca9535_read_reg(client, psa->index) >> 8)); ++} ++ ++/* ++ * sysfs callback function. ++ */ ++static ssize_t pca9535_store(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct sensor_device_attribute *psa = to_sensor_dev_attr(attr); ++ struct i2c_client *client = to_i2c_client(dev); ++ unsigned long val = simple_strtoul(buf, NULL, 0); ++ unsigned long old = pca9535_read_reg(client, psa->index); ++ ++ if (val > 0xff) ++ return -EINVAL; ++ ++ val = (old & 0xff) | (val << 8); ++ pca9535_write_reg(client, psa->index, val); ++ return count; ++} ++ ++#define PCA9535_ENTRY_RO(name, cmd_idx) \ ++ static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9535_show, NULL, cmd_idx) ++ ++#define PCA9535_ENTRY_RW(name, cmd_idx) \ ++ static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9535_show, \ ++ pca9535_store, cmd_idx) ++ ++PCA9535_ENTRY_RO(input0, PCA9535_INPUT_0); ++PCA9535_ENTRY_RO(input1, PCA9535_INPUT_1); ++PCA9535_ENTRY_RW(output0, PCA9535_OUTPUT_0); ++PCA9535_ENTRY_RW(output1, PCA9535_OUTPUT_1); ++PCA9535_ENTRY_RW(invert0, PCA9535_INVERT_0); ++PCA9535_ENTRY_RW(invert1, PCA9535_INVERT_1); ++PCA9535_ENTRY_RW(direction0, PCA9535_DIRECTION_0); ++PCA9535_ENTRY_RW(direction1, PCA9535_DIRECTION_1); ++ ++static struct attribute *pca9535_attributes[] = { ++ &sensor_dev_attr_input0.dev_attr.attr, ++ &sensor_dev_attr_input1.dev_attr.attr, ++ &sensor_dev_attr_output0.dev_attr.attr, ++ &sensor_dev_attr_output1.dev_attr.attr, ++ &sensor_dev_attr_invert0.dev_attr.attr, ++ &sensor_dev_attr_invert1.dev_attr.attr, ++ &sensor_dev_attr_direction0.dev_attr.attr, ++ &sensor_dev_attr_direction1.dev_attr.attr, ++ NULL ++}; ++ ++static struct attribute_group pca9535_defattr_group = { ++ .attrs = pca9535_attributes, ++}; ++//End of sysfs management code. ++ ++I2C_CLIENT_INSMOD; ++ ++u32 pca9535_read_input(void) ++{ ++ return pca9535_read_reg(pca9535_i2c_client, 0); ++} ++EXPORT_SYMBOL(pca9535_read_input); ++ ++void pca9535_write_output(u16 param) ++{ ++ pca9535_write_reg(pca9535_i2c_client, 2, param); ++} ++EXPORT_SYMBOL(pca9535_write_output); ++ ++void pca9535_set_dir(u16 param) ++{ ++ pca9535_write_reg(pca9535_i2c_client, 6, param); ++} ++EXPORT_SYMBOL(pca9535_set_dir); ++ ++static int pca9535_attach_adapter(struct i2c_adapter *adapter) ++{ ++ return i2c_probe(adapter, &addr_data, pca9535_attach); ++} ++ ++static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one) ++{ ++ struct i2c_client *new_client; ++ int err = 0; ++ ++ new_client = &(pca9535_inited.client); ++ i2c_set_clientdata(new_client, 0); ++ new_client->addr = address; ++ new_client->adapter = adapter; ++ new_client->driver = &pca9535_driver; ++ strcpy(new_client->name, DRIVER_NAME); ++ ++ if ((err = i2c_attach_client(new_client))) ++ goto exit_free; ++ ++ pca9535_i2c_client = new_client; ++ ++ init_MUTEX(&pca9535_inited.lock); ++ i2c_set_clientdata(pca9535_i2c_client, &pca9535_inited); ++ ++ sysfs_create_group(&pca9535_i2c_client->dev.kobj, &pca9535_defattr_group); ++ ++ printk("pca9535_attach() ok, address = %d, zero_or_minus_one = %d\n", address, zero_or_minus_one); ++ return 0; ++ ++exit_free: ++ printk("pca9535_attach() failed, error code = %d\n", err); ++ return err; ++} ++ ++static int pca9535_detach_client(struct i2c_client *client) ++{ ++ int err; ++ ++ if ((err = i2c_detach_client(client))) { ++ dev_err(&client->dev, "Client deregistration failed, client not detached.\n"); ++ return err; ++ } ++ pca9535_i2c_client = NULL; ++ ++ return 0; ++} ++ ++static int __init pca9535_init(void) ++{ ++ return i2c_add_driver(&pca9535_driver); ++} ++ ++static void __exit pca9535_exit(void) ++{ ++ i2c_del_driver(&pca9535_driver); ++} ++ ++/* ++ * Reads the value of GPIO available via I2C. ++ */ ++int pca9535_gpio_read(int gpio){ ++ unsigned char reg = 0; ++ unsigned long val = 0; ++ ++ printk("9535_gpio_read() called\n"); ++ if(!pca9535_i2c_client) ++ return -ENODEV; ++ ++ if(gpio < GPIO0 || gpio > GPIO17) ++ return -EINVAL; ++ ++ if(gpio >= GPIO0 && gpio <= GPIO7){ ++ reg = PCA9535_INPUT_0; ++ gpio -= GPIO0; ++ }else if(gpio >= GPIO8 && gpio <= GPIO17){ ++ reg = PCA9535_INPUT_1; ++ gpio -= GPIO8; ++ } ++ ++ down(&pca9535_inited.lock); ++ ++ // Read the existing values first ++ val = pca9535_read_reg(pca9535_i2c_client, reg) >> 8; ++ val = (val >> gpio) & 0x01; ++ ++ up(&pca9535_inited.lock); ++ ++ return val; ++} ++ ++/* ++ * Set the value of I2C GPIO. ++ */ ++int pca9535_gpio_write(int gpio, unsigned char value){ ++ unsigned char in_reg = 0; ++ unsigned char out_reg = 0; ++ unsigned long val = 0; ++ unsigned long old = 0; ++ int ret = 0; ++ ++ if(!pca9535_i2c_client) ++ return -ENODEV; ++ ++ if(gpio < GPIO0 || gpio > GPIO17) ++ return -EINVAL; ++ ++ if(gpio >= GPIO0 && gpio <= GPIO7){ ++ in_reg = PCA9535_INPUT_0; ++ out_reg = PCA9535_OUTPUT_0; ++ gpio -= GPIO0; ++ }else if(gpio >= GPIO8 && gpio <= GPIO17){ ++ in_reg = PCA9535_INPUT_1; ++ out_reg = PCA9535_OUTPUT_1; ++ gpio -= GPIO8; ++ } ++ ++ down(&pca9535_inited.lock); ++ ++ // Read the existing values first ++ val = pca9535_read_reg(pca9535_i2c_client, in_reg); ++ old = val >> 8; ++ ++ switch(value){ ++ case LOW: ++ old |= (1 << gpio); ++ break; ++ case HI: ++ old &= ~(1 << gpio); ++ break; ++ default: ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ val = (val & 0xff) | (old << 8); ++ ++ // write the values back to the register ++ pca9535_write_reg(pca9535_i2c_client, out_reg, val); ++error: ++ ++ up(&pca9535_inited.lock); ++ return ret; ++} ++ ++/* ++ * Set the direction of I2C GPIO. ++ */ ++int pca9535_gpio_direction(int gpio, unsigned char direction){ ++ unsigned char reg = 0; ++ unsigned long val = 0; ++ unsigned long old = 0; ++ int ret = 0; ++ ++ if(!pca9535_i2c_client) ++ return -ENODEV; ++ ++ if(gpio < GPIO0 || gpio > GPIO17) ++ return -EINVAL; ++ ++ if(gpio >= GPIO0 && gpio <= GPIO7){ ++ reg = PCA9535_DIRECTION_0; ++ gpio -= GPIO0; ++ }else if(gpio >= GPIO8 && gpio <= GPIO17){ ++ reg = PCA9535_DIRECTION_1; ++ gpio -= GPIO8; ++ } ++ ++ down(&pca9535_inited.lock); ++ ++ // Read the existing values first ++ old = pca9535_read_reg(pca9535_i2c_client, reg); ++ val = old >> 8; ++ ++ switch(direction){ ++ case GPIO_INPUT: ++ val |= (1 << gpio); ++ break; ++ case GPIO_OUTPUT: ++ val &= ~(1 << gpio); ++ break; ++ default: ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ val = (old & 0xff) | (val << 8); ++ ++ // write the values back to the register ++ pca9535_write_reg(pca9535_i2c_client, reg, val); ++error: ++ ++ up(&pca9535_inited.lock); ++ return ret; ++} ++ ++static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr) ++{ ++ char buffer[3]; ++ int r; ++ u32 data; ++ ++ buffer[0] = regaddr; ++ buffer[1] = 0; ++ buffer[2] = 0; ++ ++ r = i2c_master_send(client, buffer, 1); ++ if (r != 1) { ++ printk(KERN_ERR "pca9535: read failed, status %d\n", r); ++ return 0xffffffff; ++ } ++ ++ r = i2c_master_recv(client, buffer, 3); ++ if (r != 3) { ++ printk(KERN_ERR "pca9535: read failed, status %d\n", r); ++ return 0xffffffff; ++ } ++ ++ data = buffer[1]; ++ data |= buffer[2] << 8; ++ //printk(KERN_ERR "%s: reading %x in %x\n", __FUNCTION__, data, regaddr); ++ ++ return data; ++} ++ ++static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 data) ++{ ++ char buffer[3]; ++ int r; ++ ++ //printk(KERN_ERR "%s: writing %x in %x\n", __FUNCTION__, data, regaddr); ++ buffer[0] = regaddr; ++ buffer[1] = data >> 8; ++ buffer[2] = data & 0xff; ++ ++ r = i2c_master_send(client, buffer, 3); ++ if (r != 3) { ++ printk(KERN_ERR "pca9535: write failed, status %d\n", r); ++ } ++} ++ ++MODULE_AUTHOR("Husam Senussi <husamsenussi@gmail.com>"); ++MODULE_DESCRIPTION("PCA9535 driver"); ++MODULE_LICENSE("GPL"); ++ ++module_init(pca9535_init); ++module_exit(pca9535_exit); +diff -Naur linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c h6300_dev/drivers/input/keyboard/omap-keypad.c +--- linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c 2006-05-17 21:41:29.000000000 +0300 ++++ h6300_dev/drivers/input/keyboard/omap-keypad.c 2006-04-24 20:53:29.000000000 +0300 +@@ -4,11 +4,12 @@ + * OMAP Keypad Driver + * + * Copyright (C) 2003 Nokia Corporation +- * Written by Timo Teräs <ext-timo.teras@nokia.com> ++ * Written by Timo Ter�s <ext-timo.teras@nokia.com> ++ * iPAQ h6300 key and joypad support added by Mika Laitio. (2005) + * + * Added support for H2 & H3 Keypad + * Copyright (C) 2004 Texas Instruments +- * ++ * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or +@@ -44,6 +45,19 @@ + #include <asm/arch/mux.h> + + #undef NEW_BOARD_LEARNING_MODE ++//#define NEW_BOARD_LEARNING_MODE 1 ++ ++/* ++ * Following 5 keypad events are not really sent to userspace. ++ * Instead if the good combination of them is sent, then that is send. ++ * (up, right, down, left, enter) ++ */ ++#define _H6300_JOYPAD_UP_RIGHT 1 // 00001 ++#define _H6300_JOYPAD_DOWN_RIGHT 2 // 00010 ++#define _h6300_JOYPAD_DOWN_LEFT 4 // 00100 ++#define _h6300_JOYPAD_UP_LEFT 8 // 01000 ++#define _H6300_JOYPAD_KEY_OK 16 // 10000 ++#define _H6300_JOYPAD_REPORT_COLUMN 4 + + static void omap_kp_tasklet(unsigned long); + static void omap_kp_timer(unsigned long); +@@ -53,6 +67,8 @@ + static int kp_enable = 1; + static int kp_cur_group = -1; + ++static int prevJoypadKeycodePressEmulated; ++ + struct omap_kp { + struct input_dev *input; + struct timer_list timer; +@@ -139,7 +155,7 @@ + for (col = 0; col < omap_kp->cols; col++) { + omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC); + +- if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) { ++ if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) { + udelay(9); + } else { + udelay(4); +@@ -169,17 +185,26 @@ + return -1; + } + ++int is_key_down(unsigned char new_state[], ++ int col, ++ int row) ++{ ++ return (new_state[col] & (1 << row)) ? 1 : 0; ++} ++ + static void omap_kp_tasklet(unsigned long data) + { + struct omap_kp *omap_kp_data = (struct omap_kp *) data; + unsigned char new_state[8], changed, key_down = 0; + int col, row; + int spurious = 0; ++ int report_key, report_col, report_row, joypad_checked; // h6300-joypad specific variables + + /* check for any changes */ + omap_kp_scan_keypad(omap_kp_data, new_state); + + /* check for changes and print those */ ++ joypad_checked = 0; + for (col = 0; col < omap_kp_data->cols; col++) { + changed = new_state[col] ^ keypad_state[col]; + key_down |= new_state[col]; +@@ -201,14 +226,177 @@ + spurious = 1; + continue; + } +- +- if (!(kp_cur_group == (key & GROUP_MASK) || +- kp_cur_group == -1)) +- continue; +- +- kp_cur_group = key & GROUP_MASK; +- input_report_key(omap_kp_data->input, key & ~GROUP_MASK, +- !!(new_state[col] & (1 << row))); ++ if (machine_is_omap_h6300() && ++ ((col == 1) || (col == _H6300_JOYPAD_REPORT_COLUMN))) ++ { ++ if (col == _H6300_JOYPAD_REPORT_COLUMN) ++ { ++ continue; ++ } ++ if ((joypad_checked == 0) && ++ ((key == _H6300_JOYPAD_KEY_OK) || ++ (key == _h6300_JOYPAD_UP_LEFT) || ++ (key == _H6300_JOYPAD_UP_RIGHT) || ++ (key == _H6300_JOYPAD_DOWN_RIGHT) || ++ (key == _h6300_JOYPAD_DOWN_LEFT))) ++ { ++ if (is_key_down(new_state, col, row)) ++ { ++ /* ++ * only enter pressed ++ * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0 ++ * --> 100100 == 36 ++ */ ++ if (new_state[1] == 36) ++ { ++ joypad_checked = 1; ++ prevJoypadKeycodePressEmulated = KEY_ENTER; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 48; //110000 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ report_row = 4; ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ } ++ /* ++ * enter, up_left and up_right sensors pressed. ++ * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT ++ * --> 110101 == 53 ++ * OR ++ * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT ++ * --> 110001 == 42 ++ * --> move to up ++ */ ++ else if ((new_state[1] == 53) || ++ (new_state[1] == 49)) ++ { ++ joypad_checked = 1; ++ prevJoypadKeycodePressEmulated = KEY_UP; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 40; //101000 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ report_row = 3; ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ } ++ /* ++ * enter, down_left and down_right sensors pressed ++ * --> 101110 == 46 ++ * OR ++ * down_left and down_right ++ * -->101010 == 42 ++ * --> move to down ++ */ ++ else if ((new_state[1] == 46) || ++ (new_state[1] == 42)) ++ { ++ joypad_checked = 1; ++ prevJoypadKeycodePressEmulated = KEY_DOWN; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 34; //100010 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ report_row = 1; ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ } ++ /* ++ * enter, up_right and down_right sensors pressed ++ * --> 111100 == 60 ++ * or ++ * down_right and up_right ++ * --> 111000 == 56 ++ * --> move to right ++ */ ++ else if ((new_state[1] == 60) || ++ (new_state[1] == 56)) ++ { ++ joypad_checked = 1; ++ prevJoypadKeycodePressEmulated = KEY_RIGHT; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 33; //100001 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ report_row = 0; ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ } ++ /* ++ * enter, up_left and down_left sensors pressed ++ * --> 100111 == 39 ++ * or up_left and down_left ++ * --> 100011 == 35 ++ * --> move to left ++ */ ++ else if ((new_state[1] == 39) || ++ (new_state[1] == 35)) ++ { ++ joypad_checked = 1; ++ prevJoypadKeycodePressEmulated = KEY_LEFT; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 36; //100100 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ report_row = 2; ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ } ++ else ++ { ++ //printk("missed new_state = %d\n", new_state[1]); ++ } ++ } ++ else ++ { ++ if (prevJoypadKeycodePressEmulated != 0) ++ { ++ // report key up event ++ joypad_checked = 1; ++ new_state[_H6300_JOYPAD_REPORT_COLUMN] = 32; //100000 ++ report_key = prevJoypadKeycodePressEmulated; ++ report_col = _H6300_JOYPAD_REPORT_COLUMN; ++ switch(prevJoypadKeycodePressEmulated) ++ { ++ case KEY_RIGHT: ++ report_row = 0; ++ break; ++ case KEY_DOWN: ++ report_row = 1; ++ break; ++ case KEY_LEFT: ++ report_row = 2; ++ break; ++ case KEY_UP: ++ report_row = 3; ++ break; ++ case KEY_ENTER: ++ report_row = 4; ++ break; ++ default: ++ printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n", ++ key); ++ report_row = 0; ++ } ++ input_report_key(omap_kp_data->input, ++ report_key, ++ new_state[report_col] & (1 << report_row)); ++ prevJoypadKeycodePressEmulated = 0; ++ } ++ } ++ } ++ } ++ else ++ { ++ if (!(kp_cur_group == (key & GROUP_MASK) || ++ kp_cur_group == -1)) ++ continue; ++ ++ kp_cur_group = key & GROUP_MASK; ++ input_report_key(omap_kp_data->input, key & ~GROUP_MASK, ++ !!(new_state[col] & (1 << row))); ++ } + #endif + } + } +@@ -348,10 +536,11 @@ + omap_set_gpio_direction(row_gpios[i], 1); + } + } ++ prevJoypadKeycodePressEmulated = 0; + + init_timer(&omap_kp->timer); + omap_kp->timer.function = omap_kp_timer; +- omap_kp->timer.data = (unsigned long) omap_kp; ++ omap_kp->timer.data = (unsigned long)omap_kp; + + /* get the irq and init timer*/ + tasklet_enable(&kp_tasklet); +@@ -376,7 +565,7 @@ + input_register_device(omap_kp->input); + + if (machine_is_omap_h2() || machine_is_omap_h3() || +- machine_is_omap_perseus2()) { ++ machine_is_omap_perseus2() || machine_is_omap_h6300()) { + omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING); + } + /* scan current status and enable interrupt */ +@@ -447,6 +636,6 @@ + module_init(omap_kp_init); + module_exit(omap_kp_exit); + +-MODULE_AUTHOR("Timo Teräs"); ++MODULE_AUTHOR("Timo Ter�s"); + MODULE_DESCRIPTION("OMAP Keypad Driver"); + MODULE_LICENSE("GPL"); +diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile h6300_dev/drivers/input/touchscreen/omap/Makefile +--- linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/input/touchscreen/omap/Makefile 2005-10-22 03:52:45.000000000 +0300 +@@ -8,5 +8,6 @@ + objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_H3) += ts_hx.o + objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += ts_inn1510.o + objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_OSK) += ts_osk.o ++objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += ts_hx.o + + omapts-objs := omap_ts.o $(objs-yy) +diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c h6300_dev/drivers/input/touchscreen/omap/omap_ts.c +--- linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/input/touchscreen/omap/omap_ts.c 2006-02-21 23:54:33.000000000 +0200 +@@ -46,7 +46,7 @@ + #define OMAP_TS_NAME "omap_ts" + + static struct ts_device *__initdata ts_devs[] = { +-#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) ++#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) || defined(CONFIG_MACH_OMAP_H6300) + &hx_ts, + #endif + #ifdef CONFIG_MACH_OMAP_OSK +diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c h6300_dev/drivers/input/touchscreen/omap/ts_hx.c +--- linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/input/touchscreen/omap/ts_hx.c 2006-04-24 20:53:29.000000000 +0300 +@@ -39,6 +39,7 @@ + + #define H2_GPIO_NUM 4 + #define H3_GPIO_NUM 48 ++#define H6300_GPIO_NUM 2 + + #define OMAP_TSC2101_XRES 500 + #define TOUCHSCREEN_DATA_REGISTERS_PAGE 0x0 +@@ -88,6 +89,9 @@ + } else if (machine_is_omap_h3()) { + gpio = H3_GPIO_NUM; + omap_cfg_reg(W19_1610_GPIO48); ++ } else if (machine_is_omap_h6300 ()) { ++ gpio = H6300_GPIO_NUM; ++ omap_cfg_reg(M14_1510_GPIO2); + } else + return -ENODEV; + +@@ -180,5 +184,7 @@ + omap_free_gpio(H2_GPIO_NUM); + else if (machine_is_omap_h3()) + omap_free_gpio(H3_GPIO_NUM); ++ else if (machine_is_omap_h6300()) ++ omap_free_gpio(H6300_GPIO_NUM); + } + #endif +diff -Naur linux-2.6.16.16/drivers/mmc/mmc.c h6300_dev/drivers/mmc/mmc.c +--- linux-2.6.16.16/drivers/mmc/mmc.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/mmc/mmc.c 2006-03-28 10:34:39.000000000 +0300 +@@ -964,7 +964,7 @@ + mmc_decode_scr(card); + } + +- mmc_deselect_cards(host); ++ //mmc_deselect_cards(host); + } + + static unsigned int mmc_calculate_clock(struct mmc_host *host) +diff -Naur linux-2.6.16.16/drivers/ssi/omap-tsc2101.c h6300_dev/drivers/ssi/omap-tsc2101.c +--- linux-2.6.16.16/drivers/ssi/omap-tsc2101.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/ssi/omap-tsc2101.c 2006-04-24 20:53:29.000000000 +0300 +@@ -36,10 +36,11 @@ + #include <asm/arch/hardware.h> + #include <asm/hardware/tsc2101.h> + #include <asm/arch/gpioexpander.h> ++#include <asm/arch/gpio.h> + + #include "omap-tsc2101.h" + +-#if CONFIG_ARCH_OMAP16XX ++#if CONFIG_ARCH_OMAP1 + #include <../drivers/ssi/omap-uwire.h> + #else + #error "Unsupported configuration" +@@ -66,27 +67,28 @@ + if (count++ == 0) { + int ret = 0; + /* set the Mux to provide MCLK to TSC2101 */ +- if (machine_is_omap_h3()) { ++ if (machine_is_omap_h3()) + ret = omap_cfg_reg(V5_1710_MCLK_ON); +- } else { +- if (machine_is_omap_h2()) { +- ret = omap_cfg_reg(R10_1610_MCLK_ON); ++ else if (machine_is_omap_h2()) ++ ret = omap_cfg_reg(R10_1610_MCLK_ON); ++ else if (machine_is_omap_h6300()) ++ ret = omap_cfg_reg(R10_1510_MCLK_ON); ++ ++ if (!cpu_is_omap1510 ()) { ++ /* Get the MCLK */ ++ tsc2101_mclk_ck = clk_get(NULL, "mclk"); ++ if (NULL == tsc2101_mclk_ck) { ++ printk(KERN_ERR "Unable to get the clock MCLK!!!\n");; ++ ret = -EPERM; ++ goto done; + } +- } +- +- /* Get the MCLK */ +- tsc2101_mclk_ck = clk_get(NULL, "mclk"); +- if (NULL == tsc2101_mclk_ck) { +- printk(KERN_ERR "Unable to get the clock MCLK!!!\n");; +- ret = -EPERM; +- goto done; +- } +- if (clk_set_rate(tsc2101_mclk_ck, 12000000)) { +- printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");; +- ret = -EPERM; +- goto done; +- } +- clk_enable(tsc2101_mclk_ck); ++ if (clk_set_rate(tsc2101_mclk_ck, 12000000)) { ++ printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");; ++ ret = -EPERM; ++ goto done; ++ } ++ clk_enable(tsc2101_mclk_ck); ++ } /* if (!cpu_is_omap1510 ()) */ + + ret = omap_tsc2101_configure(); + +@@ -116,10 +118,16 @@ + } + } + +- /* Release the MCLK */ +- clk_disable(tsc2101_mclk_ck); +- clk_put(tsc2101_mclk_ck); +- tsc2101_mclk_ck = NULL; ++ if (!cpu_is_omap1510 ()) { ++ /* Release the MCLK */ ++ clk_disable(tsc2101_mclk_ck); ++ clk_put(tsc2101_mclk_ck); ++ tsc2101_mclk_ck = NULL; ++ } ++ ++#if defined(CONFIG_MACH_OMAP_H6300) ++ omap_free_gpio(8); ++#endif + + module_put(THIS_MODULE); + } +@@ -150,7 +158,10 @@ + return; + } + } +- if (machine_is_omap_h3()) { ++ if (machine_is_omap_h3() || machine_is_omap_h6300()) { ++ ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout (8, 0); + + ret = + omap_uwire_data_transfer(0, ((page << 11) | (address << 5)), +@@ -159,6 +170,8 @@ + printk(KERN_ERR + "uwire-write returned error for address %x\n", + address); ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout (8, 1); + return; + } + ret = omap_uwire_data_transfer(0, data, 16, 0, NULL, 0); +@@ -166,10 +179,14 @@ + printk(KERN_ERR + "uwire-write returned error for address %x\n", + address); ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout (8, 1); + return; + } +- } + ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout (8, 1); ++ } + } + + void omap_tsc2101_reads(int page, u8 startaddress, u16 * data, int numregs) +@@ -178,9 +195,13 @@ + if (machine_is_omap_h2()) { + cs = 1; + } +- if (machine_is_omap_h3()) { ++ if (machine_is_omap_h3() || machine_is_omap_h6300()) { + cs = 0; + } ++ ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout(8, 0); ++ + (void)omap_uwire_data_transfer(cs, (0x8000 | (page << 11) + | (startaddress << 5)), + 16, 0, NULL, 1); +@@ -188,6 +209,9 @@ + omap_uwire_data_transfer(cs, 0, 0, 16, data, 1); + } + omap_uwire_data_transfer(cs, 0, 0, 16, data, 0); ++ ++ if (machine_is_omap_h6300()) ++ omap_set_gpio_dataout(8, 1); + } + + u16 omap_tsc2101_read(int page, u8 address) +@@ -228,9 +252,24 @@ + omap_cfg_reg(N14_1610_UWIRE_CS0); + omap_uwire_configure_mode(0, uwire_flags); + } ++ if (machine_is_omap_h6300()) { ++ uwire_flags = UWIRE_READ_RISING_EDGE | UWIRE_WRITE_RISING_EDGE; ++ omap_cfg_reg(N14_1510_UWIRE_CS0); ++ omap_uwire_configure_mode(0, uwire_flags); ++ ++ omap_request_gpio(8); ++ omap_set_gpio_dataout(8, 0); ++ omap_set_gpio_direction (8, 0); ++ } + + /* Configure MCLK enable */ +- omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2); ++ if (cpu_is_omap16xx() || cpu_is_omap1710()) ++ omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2); ++ if (machine_is_omap_h6300()) { ++ omap_cfg_reg(V19_1510_UWIRE_SCLK); ++ omap_cfg_reg(W21_1510_UWIRE_SDO); ++ omap_cfg_reg(U18_1510_UWIRE_SDI); ++ } + + return 0; + } +@@ -243,5 +282,5 @@ + + MODULE_AUTHOR("Texas Instruments"); + MODULE_DESCRIPTION +- ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec."); ++ ("Glue audio driver for the TI OMAP1510/1610/OMAP1710 TSC2101 codec."); + MODULE_LICENSE("GPL"); +diff -Naur linux-2.6.16.16/drivers/ssi/omap-uwire.c h6300_dev/drivers/ssi/omap-uwire.c +--- linux-2.6.16.16/drivers/ssi/omap-uwire.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/ssi/omap-uwire.c 2006-04-24 20:53:29.000000000 +0300 +@@ -10,7 +10,7 @@ + * Ported to 2.6 uwire interface. + * Copyright (C) 2004 Texas Instruments. + * +- * Generalization patches by Juha Yrjölä <juha.yrjola@nokia.com> ++ * Generalization patches by Juha Yrj�l� <juha.yrjola@nokia.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the +@@ -212,6 +212,10 @@ + omap_cfg_reg(N14_1610_UWIRE_CS0); + omap_cfg_reg(P15_1610_UWIRE_CS3); + } ++ if (machine_is_omap_h6300()) { ++ omap_cfg_reg(N14_1510_UWIRE_CS0); ++ omap_cfg_reg(P15_1510_UWIRE_CS3); ++ } + if (machine_is_omap_perseus2()) { + /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */ + int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000; +diff -Naur linux-2.6.16.16/drivers/telephony/Kconfig h6300_dev/drivers/telephony/Kconfig +--- linux-2.6.16.16/drivers/telephony/Kconfig 2006-05-11 04:56:24.000000000 +0300 ++++ h6300_dev/drivers/telephony/Kconfig 2005-10-06 02:34:39.000000000 +0300 +@@ -41,7 +41,18 @@ + help + Say Y here to configure in PCMCIA service support for the Quicknet + cards manufactured by Quicknet Technologies, Inc. This changes the +- card initialization code to work with the card manager daemon. ++ card initialization code to work with the card manager daemon. ++ ++config GSM_H6300 ++ tristate "H6300 P5186 GSM/GPRS DRIVER" ++ depends on PHONE && I2C && PCA9535 ++ help ++ Bluetooth H6300 P5186 gsm/gprs driver. ++ This driver provides the firmware loading mechanism for the P5185 ++ gsm/gprs hardware in iPAQ h6300. ++ ++ Say Y here to compile support for P5186 gsm/gprs devices into the ++ kernel or say M to compile it as module (h6300_gsm). + + endmenu + +diff -Naur linux-2.6.16.16/drivers/telephony/Makefile h6300_dev/drivers/telephony/Makefile +--- linux-2.6.16.16/drivers/telephony/Makefile 2006-05-11 04:56:24.000000000 +0300 ++++ h6300_dev/drivers/telephony/Makefile 2005-10-06 02:34:39.000000000 +0300 +@@ -2,6 +2,7 @@ + # Makefile for drivers/telephony + # + +-obj-$(CONFIG_PHONE) += phonedev.o +-obj-$(CONFIG_PHONE_IXJ) += ixj.o +-obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o ++obj-$(CONFIG_PHONE) += phonedev.o ++obj-$(CONFIG_PHONE_IXJ) += ixj.o ++obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o ++obj-$(CONFIG_GSM_H6300) += omap/ +diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c h6300_dev/drivers/telephony/omap/h6300_gsm_led.c +--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.c 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,40 @@ ++/* ++ * GSM interface driver helper for controlling bluetooth leds available in iPAQ h6300. ++ * ++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch/gpio.h> ++ ++/* ++ * Low level access for disabling h6300 gsm led. ++ * ++ * TODO: implement for h6300 ++ */ ++void h6300_clear_gsm_led(int led_num) ++{ ++ printk(KERN_NOTICE "h6300_gsm_led.c h6300_clear_gsm_led() done\n"); ++ //hx4700_set_led(led_num, 0, 16); ++} ++EXPORT_SYMBOL(h6300_clear_gsm_led); ++ ++/* ++ * Low level access for setting up the gsm led. ++ * ++ * TODO: implement for h6300 ++ */ ++void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time) ++{ ++ printk(KERN_NOTICE "h6300_gsm_led.c h6300_set_gsm_led() done\n"); ++} ++EXPORT_SYMBOL(h6300_set_gsm_led); +diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h h6300_dev/drivers/telephony/omap/h6300_gsm_led.h +--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.h 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,10 @@ ++#ifndef H6300_GSM_LED_H_ ++#define H6300_GSM_LED_H_ ++ ++#define INDEX_GSM_LED 1 ++ ++void h6300_clear_gsm_led(int led_num); ++void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time); ++ ++ ++#endif /*H6300_GSM_LED_H_*/ +diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c +--- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c 2006-01-23 00:09:23.000000000 +0200 +@@ -0,0 +1,172 @@ ++/* ++ * Wavecom P5186 GPRS and GSM module driver for iPAQ h6300. ++ * ++ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++ ++#include <asm/hardware.h> ++#include <asm/arch/gpio.h> ++ ++#include <asm/arch/pca9535.h> ++#include <asm/arch/h6300_uart_info.h> ++#include "h6300_gsm_led.h" ++ ++static void ++h6300_gsm_configure(struct uart_omap_port *up, int enable) ++{ ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() started, enable = %d\n", enable); ++ ++ // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable ); ++ if (enable == 0) { ++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_OFF); // turn off gpio ++ mdelay(5); ++ h6300_clear_gsm_led(INDEX_GSM_LED); ++ } ++ else if (enable == 1) { ++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio ++ mdelay(5); ++ } ++ else if (enable == 2) { ++ h6300_set_gsm_led(INDEX_GSM_LED, 16, 16); ++ } ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() done\n"); ++} ++ ++static void ++h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx) ++{ ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_set_txrx(), txrx = %d done\n", txrx); ++ /* do nothing */ ++} ++ ++static int ++h6300_gsm_get_txrx(struct uart_omap_port *up) ++{ ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_get_txrx() done\n"); ++ /* do nothing */ ++ return 0; ++} ++ ++static int ++h6300_gsm_probe(struct platform_device *pdev) ++{ ++ int ii; ++ int curVal; ++ ++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data; ++/* ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_probe() started\n"); ++ for (ii = 0; ii < 8; ii++) ++ { ++ curVal = pca9535_gpio_read(ii); ++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal); ++ } ++ for (ii = 10; ii < 18; ii++) ++ { ++ curVal = pca9535_gpio_read(ii); ++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal); ++ } ++ printk(KERN_NOTICE "\nfirst check done\n"); ++*/ ++ pca9535_gpio_direction(GPIO_I2C_GPRS_RESET, GPIO_DIR_OUTPUT); // set gpio direction to be output ++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio ++ mdelay(200); ++ ++ pca9535_gpio_direction(GPIO_I2C_MIC_OP_EN, GPIO_DIR_OUTPUT); // set gpio direction to be output ++ pca9535_gpio_write(GPIO_I2C_MIC_OP_EN, GPIO_VALUE_ON); // turn on gpio ++ mdelay(200); ++ ++ pca9535_gpio_direction(GPIO_I2C_SPK_OP_PD, GPIO_DIR_OUTPUT); // set gpio direction to be output ++ pca9535_gpio_write(GPIO_I2C_SPK_OP_PD, GPIO_VALUE_ON); // pd = pulldown?, normal off = on ++ ++ mdelay(200); ++ ++ //pca9535_gpio_direction( ++ /* configure bluetooth UART */ ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD); ++ //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD); ++ ++ funcs->configure = h6300_gsm_configure; ++ funcs->set_txrx = h6300_gsm_set_txrx; ++ funcs->get_txrx = h6300_gsm_get_txrx; ++ ++ /* Make sure the LED is off */ ++ h6300_clear_gsm_led(INDEX_GSM_LED); ++/* ++ for (ii = 0; ii < 8; ii++) ++ { ++ curVal = pca9535_gpio_read(ii); ++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal); ++ } ++ for (ii = 10; ii < 18; ii++) ++ { ++ curVal = pca9535_gpio_read(ii); ++ printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal); ++ } ++*/ ++ printk(KERN_NOTICE "\nh6300_gsm_p5186.c h6300_gsm_probe() done\n"); ++ ++ return 0; ++} ++ ++static int ++h6300_gsm_remove(struct platform_device *pdev) ++{ ++ struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data; ++ ++ printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_remove() started\n"); ++ ++ pca9535_gpio_write(GPIO_I2C_GPRS_RESET, 0); // turn off gpio ++ ++ funcs->configure = NULL; ++ funcs->set_txrx = NULL; ++ funcs->get_txrx = NULL; ++ ++ /* Make sure the LED is off */ ++ h6300_clear_gsm_led(INDEX_GSM_LED); ++ ++ printk(KERN_NOTICE "h6300_gsm_p5186.c, h6300_gsm_remove() done\n"); ++ ++ return 0; ++} ++ ++static struct platform_driver gsm_driver = { ++ .probe = h6300_gsm_probe, ++ .remove = h6300_gsm_remove, ++ .driver = { ++ .name = "h6300_gsm", ++ }, ++}; ++ ++static int __init ++h6300_gsm_init(void) ++{ ++ printk(KERN_NOTICE "h6300 GSM Driver init()\n"); ++ return platform_driver_register(&gsm_driver); ++} ++ ++static void __exit ++h6300_gsm_exit(void) ++{ ++ printk(KERN_NOTICE "h6300 GSM Driver exit()\n"); ++ platform_driver_unregister(&gsm_driver); ++} ++ ++module_init(h6300_gsm_init); ++module_exit(h6300_gsm_exit); ++ ++MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>"); ++MODULE_DESCRIPTION("iPAQ h6300 Wavecom P5186 GPRS and GSM module driver."); ++MODULE_LICENSE("GPL"); ++ +diff -Naur linux-2.6.16.16/drivers/telephony/omap/Makefile h6300_dev/drivers/telephony/omap/Makefile +--- linux-2.6.16.16/drivers/telephony/omap/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/telephony/omap/Makefile 2005-10-06 02:34:39.000000000 +0300 +@@ -0,0 +1,6 @@ ++# ++# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers. ++# ++ ++h6300_gsm-objs := h6300_gsm_led.o h6300_gsm_p5186.o ++obj-$(CONFIG_GSM_H6300) += h6300_gsm.o +diff -Naur linux-2.6.16.16/drivers/usb/gadget/omap_udc.c h6300_dev/drivers/usb/gadget/omap_udc.c +--- linux-2.6.16.16/drivers/usb/gadget/omap_udc.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/usb/gadget/omap_udc.c 2006-04-24 20:53:29.000000000 +0300 +@@ -60,7 +60,8 @@ + #undef USB_TRACE + + /* bulk DMA seems to be behaving for both IN and OUT */ +-#define USE_DMA ++//#define USE_DMA ++#undef USE_DMA + + /* ISO too */ + #define USE_ISO +@@ -2147,7 +2148,7 @@ + /* boards that don't have VBUS sensing can't autogate 48MHz; + * can't enter deep sleep while a gadget driver is active. + */ +- if (machine_is_omap_innovator() || machine_is_omap_osk()) ++ if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300()) + omap_vbus_session(&udc->gadget, 1); + + done: +@@ -2170,7 +2171,7 @@ + if (udc->dc_clk != NULL) + omap_udc_enable_clock(1); + +- if (machine_is_omap_innovator() || machine_is_omap_osk()) ++ if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300()) + omap_vbus_session(&udc->gadget, 0); + + if (udc->transceiver) +@@ -2791,7 +2792,7 @@ + hmc = HMC_1510; + type = "(unknown)"; + +- if (machine_is_omap_innovator()) { ++ if (machine_is_omap_innovator() || machine_is_omap_h6300()) { + /* just set up software VBUS detect, and then + * later rig it so we always report VBUS. + * FIXME without really sensing VBUS, we can't +diff -Naur linux-2.6.16.16/drivers/usb/host/ohci-omap.c h6300_dev/drivers/usb/host/ohci-omap.c +--- linux-2.6.16.16/drivers/usb/host/ohci-omap.c 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/usb/host/ohci-omap.c 2006-02-06 15:36:21.000000000 +0200 +@@ -353,11 +353,7 @@ + if (IS_ERR(usb_host_ck)) + return PTR_ERR(usb_host_ck); + +- if (!cpu_is_omap1510()) +- usb_dc_ck = clk_get(0, "usb_dc_ck"); +- else +- usb_dc_ck = clk_get(0, "lb_ck"); +- ++ usb_dc_ck = clk_get(0, "usb_dc_ck"); + if (IS_ERR(usb_dc_ck)) { + clk_put(usb_host_ck); + return PTR_ERR(usb_dc_ck); +diff -Naur linux-2.6.16.16/drivers/video/omap/lcd_h6300.c h6300_dev/drivers/video/omap/lcd_h6300.c +--- linux-2.6.16.16/drivers/video/omap/lcd_h6300.c 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/drivers/video/omap/lcd_h6300.c 2006-04-24 20:53:29.000000000 +0300 +@@ -0,0 +1,159 @@ ++/* ++ * File: drivers/video/omap_new/lcd-h6300.c ++ * ++ * LCD panel support for the TI OMAP1510 Innovator board ++ * ++ * Copyright (C) 2004 Nokia Corporation ++ * Author: Imre Deak <imre.deak@nokia.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <asm/io.h> ++ ++#include <asm/arch/pca9535.h> ++#include <asm/arch/omapfb.h> ++ ++/* #define OMAPFB_DBG 1 */ ++ ++#include "debug.h" ++ ++//static struct clk *h6300_lcd_ck; ++ ++static int h6300_panel_init(struct omapfb_device *fbdev) ++{ ++ DBGENTER(1); ++/* ++ if ((h6300_lcd_ck = clk_get (NULL, "lcd_ck")) == NULL) { ++ printk(KERN_ERR "Unable to get the clock LCD_CK!!!\n"); ++ return -EPERM; ++ } clk_enable(h6300_lcd_ck); ++*/ ++ DBGLEAVE(1); ++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_init() done\n"); ++ return 0; ++} ++ ++static void h6300_panel_cleanup(void) ++{ ++ DBGENTER(1); ++/* ++ if (h6300_lcd_ck) { ++ clk_disable(h6300_lcd_ck); ++ clk_put(h6300_lcd_ck); ++ h6300_lcd_ck = NULL; ++ } ++*/ ++ DBGLEAVE(1); ++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_cleanup() done\n"); ++} ++ ++static int h6300_panel_enable(void) ++{ ++ DBGENTER(1); ++ DBGLEAVE(1); ++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_enable() done\n"); ++ return 0; ++} ++ ++static void h6300_panel_disable(void) ++{ ++ DBGENTER(1); ++ DBGLEAVE(1); ++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_disable() done\n"); ++} ++ ++static unsigned long h6300_panel_get_caps(void) ++{ ++ printk(KERN_INFO "lcd_h6300.c: h6300_panel_get_caps() called\n"); ++ return 0; ++} ++ ++struct lcd_panel h6300_panel = { ++ .name = "h6300", ++ .config = OMAP_LCDC_PANEL_TFT, ++ ++ .bpp = 16, ++ .data_lines = 16, ++ .x_res = 240, ++ .y_res = 320, ++ .pixel_clock = 21000, ++ .hsw = 12, ++ .hfp = 10, ++ .hbp = 10, ++ .vsw = 3, ++ .vfp = 10, ++ .vbp = 3, ++ .pcd = 0, ++ ++ .init = h6300_panel_init, ++ .cleanup = h6300_panel_cleanup, ++ .enable = h6300_panel_enable, ++ .disable = h6300_panel_disable, ++ .get_caps = h6300_panel_get_caps, ++}; ++ ++static int h6300_panel_probe(struct platform_device *pdev) ++{ ++ DBGENTER(1); ++ omapfb_register_panel(&h6300_panel); ++ return 0; ++} ++ ++static int h6300_panel_remove(struct platform_device *pdev) ++{ ++ DBGENTER(1); ++ return 0; ++} ++ ++static int h6300_panel_suspend(struct platform_device *pdev, pm_message_t mesg) ++{ ++ DBGENTER(1); ++ pca9535_gpio_write(GPIO3, HI); ++ return 0; ++} ++ ++static int h6300_panel_resume(struct platform_device *pdev) ++{ ++ DBGENTER(1); ++ pca9535_gpio_write(GPIO3, LOW); ++ return 0; ++} ++ ++struct platform_driver h6300_panel_driver = { ++ .probe = h6300_panel_probe, ++ .remove = h6300_panel_remove, ++ .suspend = h6300_panel_suspend, ++ .resume = h6300_panel_resume, ++ .driver = { ++ .name = "lcd_h6300", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int h6300_panel_drv_init(void) ++{ ++ return platform_driver_register(&h6300_panel_driver); ++} ++ ++static void h6300_panel_drv_cleanup(void) ++{ ++ platform_driver_unregister(&h6300_panel_driver); ++} ++ ++module_init(h6300_panel_drv_init); ++module_exit(h6300_panel_drv_cleanup); +diff -Naur linux-2.6.16.16/drivers/video/omap/Makefile h6300_dev/drivers/video/omap/Makefile +--- linux-2.6.16.16/drivers/video/omap/Makefile 2006-05-17 21:41:30.000000000 +0300 ++++ h6300_dev/drivers/video/omap/Makefile 2006-02-21 23:54:33.000000000 +0200 +@@ -23,6 +23,7 @@ + objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o + objs-y$(CONFIG_MACH_OMAP_PERSEUS2) += lcd_p2.o + objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o ++objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += lcd_h6300.o + + objs-y$(CONFIG_FB_OMAP_LCD_LPH8923) += lcd_lph8923.o + +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h h6300_dev/include/asm-arm/arch-omap/board-h6300.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/include/asm-arm/arch-omap/board-h6300.h 2006-04-24 20:53:29.000000000 +0300 +@@ -0,0 +1,40 @@ ++/* ++ * linux/include/asm-arm/arch-omap/board-innovator.h ++ * ++ * Copyright (C) 2001 RidgeRun, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#ifndef __ASM_ARCH_OMAP_H6300_H ++#define __ASM_ARCH_OMAP_H6300_H ++ ++#ifndef OMAP_SDRAM_DEVICE ++#define OMAP_SDRAM_DEVICE D256M_1X16_4B ++#endif ++ ++#define OMAP1510P1_IMIF_PRI_VALUE 0x00 ++#define OMAP1510P1_EMIFS_PRI_VALUE 0x00 ++#define OMAP1510P1_EMIFF_PRI_VALUE 0x00 ++ ++#define NR_FPGA_IRQS 24 ++#define NR_IRQS IH_BOARD_BASE + NR_FPGA_IRQS ++ ++#endif /* __ASM_ARCH_OMAP_H6300_H */ +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h 2005-10-14 18:55:31.000000000 +0300 +@@ -0,0 +1,33 @@ ++/* ++ * Support file for calling h6300 uart configuration functions. ++ * Used at least by h6300_bt driver. ++ * ++ * Copyright (c) 2005 SDG Systems, LLC ++ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700 ++ * 2005-10-03 Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver. ++ */ ++ ++#ifndef _H6300_UART_INFO_H ++#define _H6300_UART_INFO_H ++ ++#include "omap_serial.h" ++ ++#define GPIO_BT_PWR_EN 3 ++#define GPIO_N_BT_RST 9 ++ ++#define GPIO_I2C_GPRS_RESET 16 ++#define GPIO_I2C_MIC_OP_EN 10 ++#define GPIO_I2C_SPK_OP_PD 11 ++ ++#define GPIO_VALUE_OFF 0 ++#define GPIO_VALUE_ON 1 ++ ++#define GPIO_DIR_OUTPUT 1 ++ ++struct h6300_uart_funcs { ++ void (*configure)( struct uart_omap_port *up, int state); ++ void (*set_txrx)( struct uart_omap_port *up, int txrx); ++ int (*get_txrx)( struct uart_omap_port *up); ++}; ++ ++#endif +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h h6300_dev/include/asm-arm/arch-omap/hardware.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/include/asm-arm/arch-omap/hardware.h 2006-02-06 15:36:21.000000000 +0200 +@@ -290,6 +290,10 @@ + #include "board-innovator.h" + #endif + ++#ifdef CONFIG_MACH_OMAP_H6300 ++#include "board-h6300.h" ++#endif ++ + #ifdef CONFIG_MACH_OMAP_H2 + #include "board-h2.h" + #endif +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/mux.h h6300_dev/include/asm-arm/arch-omap/mux.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/mux.h 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/include/asm-arm/arch-omap/mux.h 2006-05-18 00:38:24.000000000 +0300 +@@ -320,6 +320,13 @@ + P15_1610_UWIRE_CS3, + N15_1610_UWIRE_CS1, + ++ /* OMAP-1510 uWire */ ++ P15_1510_UWIRE_CS3, ++ N14_1510_UWIRE_CS0, ++ V19_1510_UWIRE_SCLK, ++ W21_1510_UWIRE_SDO, ++ U18_1510_UWIRE_SDI, ++ + /* OMAP-1610 Flash */ + L3_1610_FLASH_CS2B_OE, + M8_1610_FLASH_CS2B_WE, +@@ -384,6 +391,7 @@ + T20_1610_LOW_PWR, + + /* MCLK Settings */ ++ R10_1510_MCLK_ON, + V5_1710_MCLK_ON, + V5_1710_MCLK_OFF, + R10_1610_MCLK_ON, +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h h6300_dev/include/asm-arm/arch-omap/omap-alsa.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/include/asm-arm/arch-omap/omap-alsa.h 2006-03-08 13:28:16.000000000 +0200 +@@ -1,6 +1,6 @@ + /* + * linux/include/asm-arm/arch-omap/omap-alsa.h +- * ++ * + * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards. + * + * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi> +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h h6300_dev/include/asm-arm/arch-omap/omap_serial.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/include/asm-arm/arch-omap/omap_serial.h 2005-10-04 00:58:34.000000000 +0300 +@@ -0,0 +1,62 @@ ++/* ++ * Omap/h6300 serial driver private interface. ++ * Code originates from the pxa-serial.h available in the handheld org drivers ++ * for iPAQ PXA4700. ++ * ++ * Copyright (c) 2005 SDG Systems, LLC ++ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700 ++ * 2005-10-03 Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver. ++ */ ++ ++#ifndef _OMAP_SERIAL_H ++#define _OMAP_SERIAL_H ++ ++#define OMAP_SERIAL_TX 1 ++#define OMAP_SERIAL_RX 2 ++ ++#include <linux/tty.h> ++#include <linux/serial_core.h> ++ ++struct platform_omap_serial_funcs; ++ ++struct uart_omap_port { ++ struct uart_port port; ++ unsigned char ier; ++ unsigned char lcr; ++ unsigned char mcr; ++ unsigned int lsr_break_flag; ++ unsigned int cken; ++ char *name; ++ struct platform_omap_serial_funcs *pf; ++}; ++ ++/* A pointer to such a structure can be contained in the platform_data ++ * field of every PXA UART platform_device. If the field is NULL, the ++ * serial port works as usual. ++ * ++ * For the sake of simplicity/performance no one of the function pointers ++ * in the structure below can be NULL. ++ */ ++struct platform_omap_serial_funcs { ++ /* Platform-specific function to initialize whatever is connected ++ to this serial port... enable=1 -> enable transceiver, ++ 0 -> disable transceiver. */ ++ void (*configure) (struct uart_omap_port *up, int enable); ++ /* Platform-specific function to enable or disable the individual ++ transmitter/receiver submodules. On transceivers without echo ++ cancellation (e.g. SIR) transmitter always has priority, e.g. ++ if both bits are set, only the transmitter is enabled. */ ++ void (*set_txrx) (struct uart_omap_port *up, int txrx); ++ /* Get the current state of tx/rx (see bitflags above) */ ++ int (*get_txrx) (struct uart_omap_port *up); ++}; ++ ++/* ++ * The variables below are located in arch/arm/mach-omap/board_h6300.c ++ * Machine-specific code may want to put a pointer to a static ++ * platform_pxa_serial_funcs structure in the dev.platform_data ++ * field of the respective port device. ++ */ ++extern struct platform_device btuart_device; ++ ++#endif +diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h h6300_dev/include/asm-arm/arch-omap/pca9535.h +--- linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h 1970-01-01 02:00:00.000000000 +0200 ++++ h6300_dev/include/asm-arm/arch-omap/pca9535.h 2005-10-25 03:24:45.000000000 +0300 +@@ -0,0 +1,39 @@ ++#ifndef _PCA9535_H ++#define _PCA9535_H ++ ++enum pca9535_gpios { ++ GPIO0 = 0, ++ GPIO1 = 1, ++ GPIO2 = 2, ++ GPIO3 = 3, ++ GPIO4 = 4, ++ GPIO5 = 5, ++ GPIO6 = 6, ++ GPIO7 = 7, ++ GPIO8 = 8, ++ GPIO9 = 9, ++ GPIO10 = 10, ++ GPIO11 = 11, ++ GPIO12 = 12, ++ GPIO13 = 13, ++ GPIO14 = 14, ++ GPIO15 = 15, ++ GPIO16 = 16, ++ GPIO17 = 17 ++}; ++ ++enum gpio_values { ++ HI = 0, ++ LOW = 1 ++}; ++ ++enum gpio_direction { ++ GPIO_INPUT = 0, ++ GPIO_OUTPUT = 1 ++}; ++ ++extern int pca9535_gpio_read(int gpio); ++extern int pca9535_gpio_write(int gpio, unsigned char val); ++extern int pca9535_gpio_direction(int gpio, unsigned char direction); ++ ++#endif +diff -Naur linux-2.6.16.16/Makefile h6300_dev/Makefile +--- linux-2.6.16.16/Makefile 2006-05-17 21:41:27.000000000 +0300 ++++ h6300_dev/Makefile 2006-05-18 01:45:17.000000000 +0300 +@@ -11,7 +11,7 @@ + # expect to learn how to build the kernel reading this file. + + # Add custom flags here to avoid conflict with updates +-EXTRAVERSION := $(EXTRAVERSION)-omap2 ++EXTRAVERSION := $(EXTRAVERSION)-omap1-h6300 + + # Do not print "Entering directory ..." + MAKEFLAGS += --no-print-directory +diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c +--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c 2006-03-30 23:15:31.000000000 +0300 +@@ -96,7 +96,11 @@ + static snd_pcm_hardware_t tsc2101_snd_omap_alsa_playback = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), +- .formats = (SNDRV_PCM_FMTBIT_S16_LE), ++#ifdef CONFIG_MACH_OMAP_H6300 ++ .formats = (SNDRV_PCM_FMTBIT_S8), ++#else ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE), ++#endif + .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | +@@ -136,7 +140,7 @@ + }; + + /* +- * Simplified write for tsc Audio ++ * Simplified write for tsc2101 audio registers. + */ + inline void tsc2101_audio_write(u8 address, u16 data) + { +@@ -144,7 +148,7 @@ + } + + /* +- * Simplified read for tsc Audio ++ * Simplified read for tsc2101 audio registers. + */ + inline u16 tsc2101_audio_read(u8 address) + { +@@ -246,14 +250,17 @@ + #endif /* #ifdef TSC_MASTER */ + tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data); + +- /* program the PLLs */ ++ /* Program the PLLs. This code assumes that the 12 Mhz MCLK is in use. ++ * If MCLK rate is something else, these values must be changed. ++ * See the tsc2101 specification for the details. ++ */ + if (rate_reg_info[count].fs_44kHz) { +- /* 44.1 khz - 12 MHz Mclk */ ++ /* samplerate = (44.1kHZ / x), where x is int. */ + tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | + PLL1_PVAL(1) | PLL1_I_VAL(7)); /* PVAL 1; I_VAL 7 */ + tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490)); /* D_VAL 5264 */ + } else { +- /* 48 khz - 12 Mhz Mclk */ ++ /* samplerate = (48.kHZ / x), where x is int. */ + tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | + PLL1_PVAL(1) | PLL1_I_VAL(8)); /* PVAL 1; I_VAL 8 */ + tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780)); /* D_VAL 1920 */ +@@ -317,21 +324,14 @@ + CODEC_CLOCK); + } + curRate = (uint)clk_get_rate(tsc2101_mclk); +- DPRINTK("old clock rate = %d\n", curRate); + if (curRate != CODEC_CLOCK) { + err = clk_set_rate(tsc2101_mclk, CODEC_CLOCK); + if (err) { + printk(KERN_WARNING + "Cannot set MCLK clock rate for TSC2101 CODEC, error code = %d\n", err); +- //return -ECANCELED; ++ return -ECANCELED; + } + } +- else +- { +- printk(KERN_INFO +- "omap_alsa_tsc2101_clock_on(), no need to change rate, no need to change clock rate, rate already %d Hz.\n", +- CODEC_CLOCK); +- } + err = clk_enable(tsc2101_mclk); + curRate = (uint)clk_get_rate(tsc2101_mclk); + curUseCount = clk_get_usecount(tsc2101_mclk); +@@ -349,8 +349,7 @@ + } + + /* +- * Do some sanity check, turn clock off and then turn +- * codec audio off ++ * Do some sanity check, turn clock off and then turn codec audio off + */ + int tsc2101_clock_off(void) + { +@@ -374,10 +373,6 @@ + tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL, + ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC)); + DPRINTK("audio codec off\n"); +-#ifdef DUMP_TSC2101_AUDIO_REGISTERS +- printk("tsc2101_clock_off()\n"); +- dump_tsc2101_audio_reg(); +-#endif + return 0; + } + +@@ -420,18 +415,22 @@ + }; + + static int __init omap_alsa_tsc2101_init(void) +-{ +- int err; +- ++{ + ADEBUG(); +- err = platform_driver_register(&omap_alsa_driver); +- +- return err; ++#ifdef DUMP_TSC2101_AUDIO_REGISTERS ++ printk("omap_alsa_tsc2101_init()\n"); ++ dump_tsc2101_audio_reg(); ++#endif ++ return platform_driver_register(&omap_alsa_driver); + } + + static void __exit omap_alsa_tsc2101_exit(void) + { + ADEBUG(); ++#ifdef DUMP_TSC2101_AUDIO_REGISTERS ++ printk("omap_alsa_tsc2101_exit()\n"); ++ dump_tsc2101_audio_reg(); ++#endif + platform_driver_unregister(&omap_alsa_driver); + } + +diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c +--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c 2006-05-10 02:42:13.000000000 +0300 +@@ -50,47 +50,53 @@ + //#define M_DPRINTK(ARGS...) printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS) + #define M_DPRINTK(ARGS...) /* nop */ + ++#define CHECK_BIT(INDX, ARG) (((ARG) & TSC2101_BIT(INDX)) >> INDX) ++#define IS_UNMUTED(INDX, ARG) (((CHECK_BIT(INDX, ARG)) == 0)) ++ + #define DGC_DALVL_EXTRACT(ARG) ((ARG & 0x7f00) >> 8) + #define DGC_DARVL_EXTRACT(ARG) ((ARG & 0x007f)) +-#define GET_DGC_DALMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15) +-#define GET_DGC_DARMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(7)) >> 7) +-#define IS_DGC_DALMU_UNMUTED(ARG) (((GET_DGC_DALMU_BIT_VALUE(ARG)) == 0)) +-#define IS_DGC_DARMU_UNMUTED(ARG) (((GET_DGC_DARMU_BIT_VALUE(ARG)) == 0)) + + #define HGC_ADPGA_HED_EXTRACT(ARG) ((ARG & 0x7f00) >> 8) +-#define GET_DGC_HGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15) +-#define IS_DGC_HGCMU_UNMUTED(ARG) (((GET_DGC_HGCMU_BIT_VALUE(ARG)) == 0)) +- + #define HNGC_ADPGA_HND_EXTRACT(ARG) ((ARG & 0x7f00) >> 8) +-#define GET_DGC_HNGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15) +-#define IS_DGC_HNGCMU_UNMUTED(ARG) (((GET_DGC_HNGCMU_BIT_VALUE(ARG)) == 0)) ++#define BGC_ADPGA_BGC_EXTRACT(ARG) ((ARG & 0x7f00) >> 8) + + static int current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER; + static int current_rec_src = REC_SRC_SINGLE_ENDED_MICIN_HED; + ++/* ++ * Simplified write for the tsc2101 audio registers. ++ */ ++inline void omap_tsc2101_audio_write(u8 address, u16 data) ++{ ++ omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data); ++} ++ ++/* ++ * Simplified read for the tsc2101 audio registers. ++ */ ++inline u16 omap_tsc2101_audio_read(u8 address) ++{ ++ return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address)); ++} ++ + /* +- * Used for switching between TSC2101 recourd sources. +- * Logic is adjusted from the TSC2101 OSS code. ++ * For selecting tsc2101 recourd source. + */ +-static int set_record_source(int val) ++static void set_record_source(int val) + { + u16 data; +- int maskedVal; + +- FN_IN; +- maskedVal = 0xe0 & val; +- +- data = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_MIXER_PGA_CTRL); ++ /* Mute Analog Sidetone ++ * Analog sidetone gain db? ++ * Input selected by MICSEL connected to ADC ++ */ ++ data = MPC_ASTMU | MPC_ASTG(0x45); + data &= ~MPC_MICSEL(7); /* clear all MICSEL bits */ +- data |= maskedVal; +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_MIXER_PGA_CTRL, +- data); ++ data |= MPC_MICSEL(val); ++ data |= MPC_MICADC; ++ omap_tsc2101_audio_write(TSC2101_MIXER_PGA_CTRL, data); ++ + current_rec_src = val; +- +- FN_OUT(0); +- return 0; + } + + /* +@@ -147,32 +153,34 @@ + volL = get_mixer_volume_as_dac_gain_control_volume(mixerVolL); + volR = get_mixer_volume_as_dac_gain_control_volume(mixerVolR); + +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); + /* keep the old mute bit settings */ + val &= ~(DGC_DALVL(OUTPUT_VOLUME_MIN) | DGC_DARVL(OUTPUT_VOLUME_MIN)); + val |= DGC_DALVL(volL) | DGC_DARVL(volR); + retVal = 2; + if (retVal) { +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_DAC_GAIN_CTRL, +- val); ++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val); + } + M_DPRINTK("to registry: left = %d, right = %d, total = %d\n", DGC_DALVL_EXTRACT(val), DGC_DARVL_EXTRACT(val), val); + return retVal; + } + +-int dac_gain_control_unmute_control(int muteLeft, int muteRight) ++/** ++ * If unmuteLeft/unmuteRight == 0 --> mute ++ * If unmuteLeft/unmuteRight == 1 --> unmute ++ */ ++int dac_gain_control_unmute(int unmuteLeft, int unmuteRight) + { + u16 val; + int count; + + count = 0; +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); + /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on + * so if values are same, it's time to change the registry value. + */ +- if (muteLeft == GET_DGC_DALMU_BIT_VALUE(val)) { +- if (muteLeft == 0) { ++ if (unmuteLeft != IS_UNMUTED(15, val)) { ++ if (unmuteLeft == 0) { + /* mute --> turn bit on */ + val = val | DGC_DALMU; + } +@@ -182,8 +190,8 @@ + } + count++; + } /* L */ +- if (muteRight == GET_DGC_DARMU_BIT_VALUE(val)) { +- if (muteRight == 0) { ++ if (unmuteRight != IS_UNMUTED(7, val)) { ++ if (unmuteRight == 0) { + /* mute --> turn bit on */ + val = val | DGC_DARMU; + } +@@ -194,14 +202,47 @@ + count++; + } /* R */ + if (count) { +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL, val); ++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val); + M_DPRINTK("changed value, is_unmuted left = %d, right = %d\n", +- IS_DGC_DALMU_UNMUTED(val), +- IS_DGC_DARMU_UNMUTED(val)); ++ IS_UNMUTED(15, val), ++ IS_UNMUTED(7, val)); + } + return count; + } + ++/** ++ * unmute: 0 --> mute, 1 --> unmute ++ * page2RegIndx: Registry index in tsc2101 page2. ++ * muteBitIndx: Index number for the bit in registry that indicates whether muted or unmuted. ++ */ ++int adc_pga_unmute_control(int unmute, int page2regIndx, int muteBitIndx) ++{ ++ int count; ++ u16 val; ++ ++ count = 0; ++ val = omap_tsc2101_audio_read(page2regIndx); ++ /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on ++ * so if the values are same, it's time to change the registry value... ++ */ ++ if (unmute != IS_UNMUTED(muteBitIndx, val)) { ++ if (unmute == 0) { ++ /* mute --> turn bit on */ ++ val = val | TSC2101_BIT(muteBitIndx); ++ } ++ else { ++ /* unmute --> turn bit off */ ++ val = val & ~TSC2101_BIT(muteBitIndx); ++ } ++ M_DPRINTK("changed value, is_unmuted = %d\n", IS_UNMUTED(muteBitIndx, val)); ++ count++; ++ } ++ if (count) { ++ omap_tsc2101_audio_write(page2regIndx, val); ++ } ++ return count; ++} ++ + /* + * Converts the DGC registry value read from the TSC2101 registry to + * Alsa mixer volume format (0 - 100). +@@ -271,14 +312,11 @@ + /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */ + /* NOTE: 0 is minimum volume and not mute */ + volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol); +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL); + /* preserve the old mute settings */ + val &= ~(HGC_ADPGA_HED(INPUT_VOLUME_MAX)); + val |= HGC_ADPGA_HED(volume); +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL, +- val); ++ omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val); + retVal = 1; + + M_DPRINTK("to registry = %d\n", val); +@@ -305,71 +343,37 @@ + * NOTE: 0 is minimum volume and not mute + */ + volume = get_mixer_volume_as_headset_gain_control_volume(mixerVol); +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL); + /* preserve the old mute settigns */ + val &= ~(HNGC_ADPGA_HND(INPUT_VOLUME_MAX)); + val |= HNGC_ADPGA_HND(volume); +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HANDSET_GAIN_CTRL, +- val); ++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val); + retVal = 1; + + M_DPRINTK("to registry = %d\n", val); + return retVal; + } + +-void init_record_sources(void) +-{ +- /* Mute Analog Sidetone +- * analog sidetone gain db? +- * Cell Phone In not connected to ADC +- * Input selected by MICSEL connected to ADC +- */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_MIXER_PGA_CTRL, +- MPC_ASTMU | MPC_ASTG(0x40) | ~MPC_CPADC | MPC_MICADC); +- /* Set record source, Select MIC_INHED input for headset */ +- set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED); +-} +- + void set_loudspeaker_to_playback_target(void) + { +- u16 val; +- +- /* power down sp1, sp2 and loudspeaker */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_CODEC_POWER_CTRL, ++ /* power down SPK1, SPK2 and loudspeaker */ ++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL, + CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF); + /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled + * 1dB AGC hysteresis + * MICes bias 2V + */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_4, +- AC4_MB_HED(0)); ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0)); + + /* DAC left and right routed to SPK1/SPK2 + * SPK1/SPK2 unmuted +- * keyclicks routed to SPK1/SPK2 +- */ +- val = AC5_DIFFIN | ++ * Keyclicks routed to SPK1/SPK2 */ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5, ++ AC5_DIFFIN | + AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 | +- AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 | +- AC5_HDSCPTC; +- val = val & ~AC5_HDSCPTC; +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_5, +- val); +- +- /* powerdown spk1/out32n and spk2 */ +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_POWERDOWN_STS); +- val = val & ~(~PS_SPK1FL | ~PS_HNDFL | PS_LSPKFL); +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_POWERDOWN_STS, +- val); +- +- /* routing selected to SPK1 goes to OUT8P/OUT84 alsa. (loudspeaker) ++ AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2); ++ ++ /* routing selected to SPK1 goes also to OUT8P/OUT8N. (loudspeaker) + * analog sidetone routed to loudspeaker + * buzzer pga routed to loudspeaker + * keyclick routing to loudspeaker +@@ -381,43 +385,242 @@ + * Enable loudspeaker short protection control (0 = enable protection) + * VGND short protection control (0 = enable protection) + */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_6, ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6, + AC6_SPL2LSK | AC6_AST2LSK | AC6_BUZ2LSK | AC6_KCL2LSK | +- AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO | +- ~AC6_MUTLSPK | ~AC6_MUTSPK2 | ~AC6_LDSCPTC | ~AC6_VGNDSCPTC); ++ AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO); + current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER; + } + + void set_headphone_to_playback_target(void) + { +- /* power down sp1, sp2 and loudspeaker */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_CODEC_POWER_CTRL, ++ /* power down SPK1, SPK2 and loudspeaker */ ++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL, + CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF); + /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */ + /* 1dB AGC hysteresis */ + /* MICes bias 2V */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_4, +- AC4_MB_HED(0)); +- +- /* DAC left and right routed to SPK2 */ +- /* SPK1/2 unmuted */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_5, ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0)); ++ ++ /* DAC left and right routed to SPK1/SPK2 ++ * SPK1/SPK2 unmuted ++ * Keyclicks routed to SPK1/SPK2 */ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5, + AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 | + AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 | + AC5_HDSCPTC); +- +- /* OUT8P/N muted, CPOUT muted */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_6, ++ ++ /* OUT8P/OUT8N muted, CPOUT muted */ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6, + AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC | + AC6_VGNDSCPTC); + current_playback_target = PLAYBACK_TARGET_HEADPHONE; + } + ++void set_telephone_to_playback_target(void) ++{ ++ /* ++ * 0110 1101 0101 1100 ++ * power down MICBIAS_HED, Analog sidetone, SPK2, DAC, ++ * Driver virtual ground, loudspeaker. Values D2-d5 are flags. ++ */ ++ omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL, ++ CPC_MBIAS_HED | CPC_ASTPWD | CPC_SP2PWDN | CPC_DAPWDN | ++ CPC_VGPWDN | CPC_LSPWDN); ++ ++ /* ++ * 0010 1010 0100 0000 ++ * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled ++ * 1dB AGC hysteresis ++ * MICes bias 2V ++ */ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, ++ AC4_MB_HND | AC4_MB_HED(0) | AC4_AGCHYS(1) | ++ AC4_BISTPD | AC4_ASSTPD | AC4_DASTPD); ++ printk("set_telephone_to_playback_target(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4)); ++ ++ /* ++ * 1110 0010 0000 0010 ++ * DAC left and right routed to SPK1/SPK2 ++ * SPK1/SPK2 unmuted ++ * keyclicks routed to SPK1/SPK2 ++ */ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5, ++ AC5_DIFFIN | AC5_DAC2SPK1(3) | ++ AC5_CPI2SPK1 | AC5_MUTSPK2); ++ ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6, ++ AC6_MIC2CPO | AC6_MUTLSPK | ++ AC6_LDSCPTC | AC6_VGNDSCPTC | AC6_CAPINTF); ++ current_playback_target = PLAYBACK_TARGET_CELLPHONE; ++} ++ ++/* ++ * 1100 0101 1101 0000 ++ * ++ * #define MPC_ASTMU TSC2101_BIT(15) ++ * #define MPC_ASTG(ARG) (((ARG) & 0x7F) << 8) ++ * #define MPC_MICSEL(ARG) (((ARG) & 0x07) << 5) ++ * #define MPC_MICADC TSC2101_BIT(4) ++ * #define MPC_CPADC TSC2101_BIT(3) ++ * #define MPC_ASTGF (0x01) ++ */ ++static void set_telephone_to_record_source(void) ++{ ++ u16 val; ++ ++ /* ++ * D0 = 0: ++ * --> AGC is off for handset input. ++ * --> ADC PGA is controlled by the ADMUT_HDN + ADPGA_HND ++ * (D15, D14-D8) ++ * D4 - D1 = 0000 ++ * --> AGC time constant for handset input, ++ * attack time = 8 mc, decay time = 100 ms ++ * D7 - D5 = 000 ++ * --> AGC Target gain for handset input = -5.5 db ++ * D14 - D8 = 011 1100 ++ * --> ADC handset PGA settings = 60 = 30 db ++ * D15 = 0 ++ * --> Handset input ON (unmuted) ++ */ ++ val = 0x3c00; // 0011 1100 0000 0000 = 60 = 30 ++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val); ++ ++ /* ++ * D0 = 0 ++ * --> AGC is off for headset/Aux input ++ * --> ADC headset/Aux PGA is contoller by ADMUT_HED + ADPGA_HED ++ * (D15, D14-D8) ++ * D4 - D1 = 0000 ++ * --> Agc constant for headset/Aux input, ++ * attack time = 8 mc, decay time = 100 ms ++ * D7 - D5 = 000 ++ * --> AGC target gain for headset input = -5.5 db ++ * D14 - D8 = 000 0000 ++ * --> Adc headset/AUX pga settings = 0 db ++ * D15 = 1 ++ * --> Headset/AUX input muted ++ * ++ * Mute headset aux input ++ */ ++ val = 0x8000; // 1000 0000 0000 0000 ++ omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val); ++ set_record_source(REC_SRC_MICIN_HND_AND_AUX1); ++ ++ // hacks start ++ /* D0 = flag, Headset/Aux or handset PGA flag ++ * --> & with 1 (= 1 -->gain applied == pga register settings) ++ * D1 = 0, DAC channel PGA soft stepping control ++ * --> 0.5 db change every WCLK ++ * D2 = flag, DAC right channel PGA flag ++ * --> & with 1 ++ * D3 = flag, DAC left channel PGA flag ++ * -- > & with 1 ++ * D7 - D4 = 0001, keyclick length ++ * --> 4 periods key clicks ++ * D10 - D8 = 100, keyclick frequenzy ++ * --> 1 kHz, ++ * D11 = 0, Headset/Aux or handset soft stepping control ++ * --> 0,5 db change every WCLK or ADWS ++ * D14 -D12 = 100, Keyclick applitude control ++ * --> Medium amplitude ++ * D15 = 0, keyclick disabled ++ */ ++ val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_2); ++ val = val & 0x441d; ++ val = val | 0x4410; // D14, D10, D4 bits == 1 ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_2, val); ++ ++ /* ++ * D0 = 0 (reserved, write always 0) ++ * D1 = flag, ++ * --> & with 1 ++ * D2 - D5 = 0000 (reserved, write always 0000) ++ * D6 = 1 ++ * --> MICBIAS_HND = 2.0 v ++ * D8 - D7 = 00 ++ * --> MICBIAS_HED = 3.3 v ++ * D10 - D9 = 01, ++ * --> Mic AGC hysteric selection = 2 db ++ * D11 = 1, ++ * --> Disable buzzer PGA soft stepping ++ * D12 = 0, ++ * --> Enable CELL phone PGA soft stepping control ++ * D13 = 1 ++ * --> Disable analog sidetone soft stepping control ++ * D14 = 0 ++ * --> Enable DAC PGA soft stepping control ++ * D15 = 0, ++ * --> Enable headset/Aux or Handset soft stepping control ++ */ ++ val = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4); ++ val = val & 0x2a42; // 0010 1010 0100 0010 ++ val = val | 0x2a40; // bits D13, D11, D9, D6 == 1 ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, val); ++ printk("set_telephone_to_record_source(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4)); ++ /* ++ * D0 = 0 ++ * --> reserved, write always = 0 ++ * D1 = flag, read only ++ * --> & with 1 ++ * D5 - D2 = 1111, Buzzer input PGA settings ++ * --> 0 db ++ * D6 = 1, ++ * --> power down buzzer input pga ++ * D7 = flag, read only ++ * --> & with 1 ++ * D14 - D8 = 101 1101 ++ * --> 12 DB ++ * D15 = 0 ++ * --> power up cell phone input PGA ++ */ ++ val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL); ++ val = val & 0x5dfe; ++ val = val | 0x5dfe; // bits, D14, D12, D11, D10, D8, D6, D5,D4,D3,D2 ++ omap_tsc2101_audio_write(TSC2101_BUZZER_GAIN_CTRL, val); ++ ++ /* D6 - D0 = 000 1001 ++ * --> -4.5 db for DAC right channel volume control ++ * D7 = 1 ++ * --> DAC right channel muted ++ * D14 - D8 = 000 1001 ++ * --> -4.5 db for DAC left channel volume control ++ * D15 = 1 ++ * --> DAC left channel muted ++ */ ++ //val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); ++ val = 0x8989; ++ omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val); ++ ++ /* 0000 0000 0100 0000 ++ * ++ * D1 - D0 = 0 ++ * --> GPIO 1 pin output is three stated ++ * D2 = 0 ++ * --> Disaple GPIO2 for CLKOUT mode ++ * D3 = 0 ++ * --> Disable GPUI1 for interrupt detection ++ * D4 = 0 ++ * --> Disable GPIO2 for headset detection interrupt ++ * D5 = reserved, always 0 ++ * D7 - D6 = 01 ++ * --> 8 ms clitch detection ++ * D8 = reserved, write only 0 ++ * D10 -D9 = 00 ++ * --> 16 ms de bouncing programmatitily ++ * for glitch detection during headset detection ++ * D11 = flag for button press ++ * D12 = flag for headset detection ++ * D14-D13 = 00 ++ * --> type of headset detected = 00 == no stereo headset deected ++ * D15 = 0 ++ * --> Disable headset detection ++ * ++ * */ ++ val = 0x40; ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, val); ++} ++ + /* + * Checks whether the headset is detected. + * If headset is detected, the type is returned. Type can be +@@ -433,8 +636,7 @@ + u16 curVal; + + curType = 0; /* not detected */ +- curVal = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_7); ++ curVal = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_7); + curDetected = curVal & AC7_HDDETFL; + if (curDetected) { + printk("headset detected, checking type from %d \n", curVal); +@@ -461,13 +663,10 @@ + * AGC enable for handset input + * Handset input not muted + */ +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HANDSET_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL); + val = val | HNGC_AGCEN_HND; + val = val & ~HNGC_ADMUT_HND; +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HANDSET_GAIN_CTRL, +- val); ++ omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val); + + /* mic input volume control + * SET_MIC in the OSS driver +@@ -479,7 +678,7 @@ + */ + set_mixer_volume_as_dac_gain_control_volume(DEFAULT_OUTPUT_VOLUME, DEFAULT_OUTPUT_VOLUME); + /* unmute */ +- dac_gain_control_unmute_control(1, 1); ++ dac_gain_control_unmute(1, 1); + } + + /* +@@ -490,11 +689,11 @@ + FN_IN; + + /* Headset/Hook switch detect enabled */ +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_AUDIO_CTRL_7, +- AC7_DETECT); ++ omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, AC7_DETECT); + +- init_record_sources(); ++ /* Select headset to record source (MIC_INHED)*/ ++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED); ++ /* Init loudspeaker as a default playback target*/ + init_playback_targets(); + + FN_OUT(0); +@@ -503,7 +702,7 @@ + static int __pcm_playback_target_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) + { + static char *texts[PLAYBACK_TARGET_COUNT] = { +- "Loudspeaker", "Headphone" ++ "Loudspeaker", "Headphone", "Cellphone" + }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; +@@ -533,12 +732,18 @@ + if ((curVal >= 0) && + (curVal < PLAYBACK_TARGET_COUNT) && + (curVal != current_playback_target)) { +- if (curVal == 0) { +- set_loudspeaker_to_playback_target(); ++ if (curVal == PLAYBACK_TARGET_LOUDSPEAKER) { ++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED); ++ set_loudspeaker_to_playback_target(); + } +- else { ++ else if (curVal == PLAYBACK_TARGET_HEADPHONE) { ++ set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HND); + set_headphone_to_playback_target(); + } ++ else if (curVal == PLAYBACK_TARGET_CELLPHONE) { ++ set_telephone_to_record_source(); ++ set_telephone_to_playback_target(); ++ } + retVal = 1; + } + return retVal; +@@ -563,7 +768,7 @@ + u16 volR; + u16 val; + +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); + M_DPRINTK("registry value = %d!\n", val); + volL = DGC_DALVL_EXTRACT(val); + volR = DGC_DARVL_EXTRACT(val); +@@ -603,16 +808,16 @@ + */ + static int __pcm_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL); ++ u16 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL); + +- ucontrol->value.integer.value[0] = IS_DGC_DALMU_UNMUTED(val); +- ucontrol->value.integer.value[1] = IS_DGC_DARMU_UNMUTED(val); ++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); // left ++ ucontrol->value.integer.value[1] = IS_UNMUTED(7, val); // right + return 0; + } + + static int __pcm_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- return dac_gain_control_unmute_control(ucontrol->value.integer.value[0], ++ return dac_gain_control_unmute(ucontrol->value.integer.value[0], + ucontrol->value.integer.value[1]); + } + +@@ -630,8 +835,7 @@ + u16 val; + u16 vol; + +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL); + M_DPRINTK("registry value = %d\n", val); + vol = HGC_ADPGA_HED_EXTRACT(val); + vol = vol & ~HGC_ADMUT_HED; +@@ -662,38 +866,17 @@ + */ + static int __headset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL); +- ucontrol->value.integer.value[0] = IS_DGC_HGCMU_UNMUTED(val); ++ u16 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL); ++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); + return 0; + } + + static int __headset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- int count = 0; +- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL); +- /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on +- * so if values are same, it's time to change the registry value... +- */ +- if (ucontrol->value.integer.value[0] == GET_DGC_HGCMU_BIT_VALUE(val)) { +- if (ucontrol->value.integer.value[0] == 0) { +- /* mute --> turn bit on */ +- val = val | HGC_ADMUT_HED; +- } +- else { +- /* unmute --> turn bit off */ +- val = val & ~HGC_ADMUT_HED; +- } +- count++; +- M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HGCMU_UNMUTED(val)); +- } +- if (count) { +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HEADSET_GAIN_CTRL, +- val); +- } +- return count; ++ // mute/unmute headset ++ return adc_pga_unmute_control(ucontrol->value.integer.value[0], ++ TSC2101_HEADSET_GAIN_CTRL, ++ 15); + } + + static int __handset_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) +@@ -710,7 +893,7 @@ + u16 val; + u16 vol; + +- val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL); ++ val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL); + M_DPRINTK("registry value = %d\n", val); + vol = HNGC_ADPGA_HND_EXTRACT(val); + vol = vol & ~HNGC_ADMUT_HND; +@@ -740,42 +923,74 @@ + */ + static int __handset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL); +- ucontrol->value.integer.value[0] = IS_DGC_HNGCMU_UNMUTED(val); ++ u16 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL); ++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); + return 0; + } + + static int __handset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) + { +- int count = 0; +- u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL); +- +- /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on +- * so if values are same, it's time to change the registry value... +- */ +- if (ucontrol->value.integer.value[0] == GET_DGC_HNGCMU_BIT_VALUE(val)) { +- if (ucontrol->value.integer.value[0] == 0) { +- /* mute --> turn bit on */ +- val = val | HNGC_ADMUT_HND; +- } +- else { +- /* unmute --> turn bit off */ +- val = val & ~HNGC_ADMUT_HND; +- } +- M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HNGCMU_UNMUTED(val)); +- count++; +- } +- if (count) { +- omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, +- TSC2101_HANDSET_GAIN_CTRL, +- val); +- } +- return count; ++ // handset mute/unmute ++ return adc_pga_unmute_control(ucontrol->value.integer.value[0], ++ TSC2101_HANDSET_GAIN_CTRL, ++ 15); ++} ++ ++static int __cellphone_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ return 0; ++} ++ ++/* When BGC_MUT_CP (bit 15) = 1, power down cellphone input pga. ++ * When BGC_MUT_CP = 0, power up cellphone input pga. ++ */ ++static int __cellphone_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) ++{ ++ u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL); ++ ucontrol->value.integer.value[0] = IS_UNMUTED(15, val); ++ return 0; ++} ++ ++static int __cellphone_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) ++{ ++ return adc_pga_unmute_control(ucontrol->value.integer.value[0], ++ TSC2101_BUZZER_GAIN_CTRL, ++ 15); ++} ++ ++static int __buzzer_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ return 0; ++} ++ ++/* When BGC_MUT_BU (bit 6) = 1, power down cellphone input pga. ++ * When BGC_MUT_BU = 0, power up cellphone input pga. ++ */ ++static int __buzzer_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) ++{ ++ u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL); ++ ucontrol->value.integer.value[0] = IS_UNMUTED(6, val); ++ return 0; ++} ++ ++static int __buzzer_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) ++{ ++ return adc_pga_unmute_control(ucontrol->value.integer.value[0], ++ TSC2101_BUZZER_GAIN_CTRL, ++ 6); + } + + static snd_kcontrol_new_t tsc2101_control[] __devinitdata = { + { +- .name = "Playback Playback Route", ++ .name = "Target Playback Route", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, +@@ -801,7 +1016,7 @@ + }, { + .name = "Headset Playback Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, +- .index = 1, ++ .index = 0, + .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = __headset_playback_volume_info, + .get = __headset_playback_volume_get, +@@ -809,7 +1024,7 @@ + }, { + .name = "Headset Playback Switch", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, +- .index = 1, ++ .index = 0, + .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = __headset_playback_switch_info, + .get = __headset_playback_switch_get, +@@ -817,7 +1032,7 @@ + }, { + .name = "Handset Playback Volume", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, +- .index = 2, ++ .index = 0, + .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = __handset_playback_volume_info, + .get = __handset_playback_volume_get, +@@ -825,12 +1040,28 @@ + }, { + .name = "Handset Playback Switch", + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, +- .index = 2, ++ .index = 0, + .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = __handset_playback_switch_info, + .get = __handset_playback_switch_get, + .put = __handset_playback_switch_put, +- } ++ }, { ++ .name = "Cellphone Input Switch", ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .index = 0, ++ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .info = __cellphone_input_switch_info, ++ .get = __cellphone_input_switch_get, ++ .put = __cellphone_input_switch_put, ++ }, { ++ .name = "Buzzer Input Switch", ++ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .index = 0, ++ .access= SNDRV_CTL_ELEM_ACCESS_READWRITE, ++ .info = __buzzer_input_switch_info, ++ .get = __buzzer_input_switch_get, ++ .put = __buzzer_input_switch_put, ++ } + }; + + #ifdef CONFIG_PM +diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h +--- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h 2006-03-30 23:15:31.000000000 +0300 +@@ -56,20 +56,21 @@ + #define INPUT_VOLUME_MAX 0x7D + #define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN) + +-#define PLAYBACK_TARGET_COUNT 0x02 ++#define PLAYBACK_TARGET_COUNT 0x03 + #define PLAYBACK_TARGET_LOUDSPEAKER 0x00 + #define PLAYBACK_TARGET_HEADPHONE 0x01 ++#define PLAYBACK_TARGET_CELLPHONE 0x02 + + /* following are used for register 03h Mixer PGA control bits D7-D5 for selecting record source */ + #define REC_SRC_TARGET_COUNT 0x08 +-#define REC_SRC_SINGLE_ENDED_MICIN_HED MPC_MICSEL(0) // oss code referred to MIXER_LINE +-#define REC_SRC_SINGLE_ENDED_MICIN_HND MPC_MICSEL(1) // oss code referred to MIXER_MIC +-#define REC_SRC_SINGLE_ENDED_AUX1 MPC_MICSEL(2) +-#define REC_SRC_SINGLE_ENDED_AUX2 MPC_MICSEL(3) +-#define REC_SRC_MICIN_HED_AND_AUX1 MPC_MICSEL(4) +-#define REC_SRC_MICIN_HED_AND_AUX2 MPC_MICSEL(5) +-#define REC_SRC_MICIN_HND_AND_AUX1 MPC_MICSEL(6) +-#define REC_SRC_MICIN_HND_AND_AUX2 MPC_MICSEL(7) ++#define REC_SRC_SINGLE_ENDED_MICIN_HED 0x00 // oss code referred to MIXER_LINE ++#define REC_SRC_SINGLE_ENDED_MICIN_HND 0x01 // oss code referred to MIXER_MIC ++#define REC_SRC_SINGLE_ENDED_AUX1 0x02 ++#define REC_SRC_SINGLE_ENDED_AUX2 0x03 ++#define REC_SRC_MICIN_HED_AND_AUX1 0x04 ++#define REC_SRC_MICIN_HED_AND_AUX2 0x05 ++#define REC_SRC_MICIN_HND_AND_AUX1 0x06 ++#define REC_SRC_MICIN_HND_AND_AUX2 0x07 + + #define DEFAULT_OUTPUT_VOLUME 90 // default output volume to dac dgc + #define DEFAULT_INPUT_VOLUME 20 // default record volume +diff -Naur linux-2.6.16.16/sound/oss/Kconfig h6300_dev/sound/oss/Kconfig +--- linux-2.6.16.16/sound/oss/Kconfig 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/sound/oss/Kconfig 2006-02-06 15:36:21.000000000 +0200 +@@ -13,8 +13,8 @@ + + config SOUND_OMAP_TSC2101 + tristate "TSC2101 Stereo Codec" +- depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON) +- select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 ) ++ depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON || MACH_OMAP_H6300) ++ select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H6300 ) + select OMAP_UWIRE if ARCH_OMAP1 + ---help--- + Tsc2101 Audio Codec Driver for OMAP will be enabled. +diff -Naur linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c h6300_dev/sound/oss/omap-audio-tsc2101.c +--- linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c 2006-05-17 21:41:31.000000000 +0300 ++++ h6300_dev/sound/oss/omap-audio-tsc2101.c 2006-04-02 00:23:01.000000000 +0300 +@@ -48,7 +48,7 @@ + #include "omap-audio.h" + #include "omap-audio-dma-intfc.h" + #include <asm/arch/mcbsp.h> +-#ifdef CONFIG_ARCH_OMAP16XX ++#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_MACH_OMAP_H6300) + #include <../drivers/ssi/omap-uwire.h> + #include <asm/arch/dsp_common.h> + #elif defined(CONFIG_ARCH_OMAP24XX) +@@ -73,10 +73,16 @@ + + #ifdef CONFIG_ARCH_OMAP16XX + #define PLATFORM_NAME "OMAP16XX" ++#elif CONFIG_MACH_OMAP_H6300 ++#define PLATFORM_NAME "OMAP15XX" + #elif defined(CONFIG_ARCH_OMAP24XX) + #define PLATFORM_NAME "OMAP2" + #endif + ++#if CONFIG_ARCH_OMAP16XX ++#define OMAP_DSP_BASE 0xE0000000 ++#endif ++ + /* Define to set the tsc as the master w.r.t McBSP */ + #define TSC_MASTER + +@@ -123,7 +129,7 @@ + /*********** Debug Macros ********/ + /* To Generate a rather shrill tone -test the entire path */ + //#define TONE_GEN +-/* To Generate a tone for each keyclick - test the tsc,spi paths*/ ++///* To Generate a tone for each keyclick - test the tsc,spi paths*/ + //#define TEST_KEYCLICK + /* To dump the tsc registers for debug */ + //#define TSC_DUMP_REGISTERS +@@ -230,6 +236,17 @@ + }; + + static struct omap_mcbsp_reg_cfg initial_config = { ++#ifdef CONFIG_MACH_OMAP_H6300 ++ .spcr2 = 0x0005, ++ .spcr1 = 0x0005, ++ .rcr2 = 0x8041, ++ .rcr1 = 0x8041, ++ .xcr2 = 0x00a1, ++ .xcr1 = 0x00a1, ++ .srgr2 = 0xb000, ++ .srgr1 = 0xb000, ++ .pcr0 = 0x0081, ++#else + .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), + .spcr1 = RINTM(3) | RRST, + .rcr2 = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) | +@@ -253,6 +270,7 @@ + #endif /* tsc Master defs */ + + #endif /* platform specific inits */ ++#endif /* CONFIG_MACH_OMAP_H6300 */ + }; + + /***************************** MODULES SPECIFIC FUNCTION PROTOTYPES ********************/ |