diff -prauN linux-2.6.0-test7/Documentation/filesystems/Locking wli-2.6.0-test7-bk5-36/Documentation/filesystems/Locking --- linux-2.6.0-test7/Documentation/filesystems/Locking 2003-10-08 12:24:43.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Documentation/filesystems/Locking 2003-10-14 03:01:39.000000000 -0700 @@ -204,7 +204,7 @@ currently-in-progress I/O. If the filesystem is not called for "sync" and it determines that it would need to block against in-progress I/O to be able to start new I/O against the page the filesystem shoud redirty the page (usually with -__set_page_dirty_nobuffers()), then unlock the page and return zero. +set_page_dirty_nobuffers()), then unlock the page and return zero. This may also be done to avoid internal deadlocks, but rarely. If the filesytem is called for sync then it must wait on any diff -prauN linux-2.6.0-test7/Documentation/filesystems/jfs.txt wli-2.6.0-test7-bk5-36/Documentation/filesystems/jfs.txt --- linux-2.6.0-test7/Documentation/filesystems/jfs.txt 2003-10-08 12:24:16.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Documentation/filesystems/jfs.txt 2003-10-14 02:49:46.000000000 -0700 @@ -32,6 +32,10 @@ integrity Default. Commit metadata chan option to remount a volume where the nointegrity option was previously specified in order to restore normal behavior. +errors=continue Keep going on a filesystem error. +errors=remount-ro Default. Remount the filesystem read-only on an error. +errors=panic Panic and halt the machine if an error occurs. + JFS TODO list: Plans for our near term development items diff -prauN linux-2.6.0-test7/Documentation/filesystems/xfs.txt wli-2.6.0-test7-bk5-36/Documentation/filesystems/xfs.txt --- linux-2.6.0-test7/Documentation/filesystems/xfs.txt 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Documentation/filesystems/xfs.txt 2003-10-14 02:49:46.000000000 -0700 @@ -29,6 +29,11 @@ When mounting an XFS filesystem, the fol The preferred buffered I/O size can also be altered on an individual file basis using the ioctl(2) system call. + ikeep + When inode clusters are emptied of inodes, keep them around + on the disk, this is the old XFS behavior. Default is now to + return the inode cluster to the free space pool. + logbufs=value Set the number of in-memory log buffers. Valid numbers range from 2-8 inclusive. diff -prauN linux-2.6.0-test7/Documentation/vm/locking wli-2.6.0-test7-bk5-36/Documentation/vm/locking --- linux-2.6.0-test7/Documentation/vm/locking 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Documentation/vm/locking 2003-10-14 03:00:43.000000000 -0700 @@ -66,7 +66,7 @@ in some cases it is not really needed. E expand_stack(), it is hard to come up with a destructive scenario without having the vmlist protection in this case. -The page_table_lock nests with the inode i_shared_sem and the kmem cache +The page_table_lock nests with the inode i_shared_lock and the kmem cache c_spinlock spinlocks. This is okay, since the kmem code asks for pages after dropping c_spinlock. The page_table_lock also nests with pagecache_lock and pagemap_lru_lock spinlocks, and no code asks for memory with these locks diff -prauN linux-2.6.0-test7/Documentation/x86_64/boot-options.txt wli-2.6.0-test7-bk5-36/Documentation/x86_64/boot-options.txt --- linux-2.6.0-test7/Documentation/x86_64/boot-options.txt 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Documentation/x86_64/boot-options.txt 2003-10-14 02:49:46.000000000 -0700 @@ -20,18 +20,15 @@ Machine check APICs - nolocalapic Don't use a local or IO-APIC. This should only - be needed if you have a buggy BIOS. The newer - kernels already turn it off by default if the - BIOS didn't enable the local APIC, so it will - be hopefully not needed. - Note this code path is not very well tested, you are on - your own. - apic Use IO-APIC. Default + Unless you have an NVidia or VIA/Uniprocessor board. + Then it defaults to off. noapic Don't use the IO-APIC. - Also only lightly tested. + + disableapic Don't use the local APIC + + nolapic Don't use the local APIC (alias for i386 compatibility) pirq=... See Documentation/i386/IO-APIC.txt @@ -60,13 +57,16 @@ Timing Report when timer interrupts are lost because some code turned off interrupts for too long. - nmi_watchdog=NUMBER + nmi_watchdog=NUMBER[,panic] NUMBER can be: 0 don't use an NMI watchdog 1 use the IO-APIC timer for the NMI watchdog 2 use the local APIC for the NMI watchdog using a performance counter. Note This will use one performance counter and the local APIC's performance vector. + When panic is specified panic when an NMI watchdog timeout occurs. + This is useful when you use a panic=... timeout and need the box + quickly up again. Idle loop @@ -127,6 +127,9 @@ NUMA ACPI acpi=off Don't enable ACPI + acpi=ht Use ACPI boot table parsing, but don't enable ACPI + interpreter + acpi=force Force ACPI on (currently not needed) PCI diff -prauN linux-2.6.0-test7/Makefile wli-2.6.0-test7-bk5-36/Makefile --- linux-2.6.0-test7/Makefile 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = -test7 +EXTRAVERSION = -test7-bk5 # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff -prauN linux-2.6.0-test7/arch/alpha/mm/remap.c wli-2.6.0-test7-bk5-36/arch/alpha/mm/remap.c --- linux-2.6.0-test7/arch/alpha/mm/remap.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/alpha/mm/remap.c 2003-10-14 02:53:51.000000000 -0700 @@ -73,7 +73,7 @@ __alpha_remap_area_pages(unsigned long a spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/arm/Makefile wli-2.6.0-test7-bk5-36/arch/arm/Makefile --- linux-2.6.0-test7/arch/arm/Makefile 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -155,10 +155,8 @@ zImage Image bootpImage: vmlinux zinstall install: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ -MRPROPER_FILES += \ - include/asm-arm/arch include/asm-arm/.arch \ - include/asm-arm/constants.h* \ - include/asm-arm/mach-types.h +CLEAN_FILES += include/asm-arm/constants.h* include/asm-arm/mach-types.h +MRPROPER_FILES += include/asm-arm/arch include/asm-arm/.arch # We use MRPROPER_FILES and CLEAN_FILES now archclean: diff -prauN linux-2.6.0-test7/arch/arm/configs/lart_defconfig wli-2.6.0-test7-bk5-36/arch/arm/configs/lart_defconfig --- linux-2.6.0-test7/arch/arm/configs/lart_defconfig 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/configs/lart_defconfig 2003-10-14 02:49:46.000000000 -0700 @@ -2,76 +2,107 @@ # Automatically generated make config: don't edit # CONFIG_ARM=y -# CONFIG_EISA is not set -# CONFIG_SBUS is not set -# CONFIG_MCA is not set +CONFIG_MMU=y CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set # # Code maturity level options # CONFIG_EXPERIMENTAL=y -# CONFIG_OBSOLETE is not set +CONFIG_CLEAN_COMPILE=y +CONFIG_STANDALONE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y # # Loadable module support # CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set CONFIG_KMOD=y # # System Type # +# CONFIG_ARCH_ADIFCC is not set # CONFIG_ARCH_ANAKIN is not set -# CONFIG_ARCH_ARCA5K is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_PXA is not set # CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_CAMELOT is not set # CONFIG_ARCH_FOOTBRIDGE is not set # CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_L7200 is not set # CONFIG_ARCH_RPC is not set CONFIG_ARCH_SA1100=y # CONFIG_ARCH_SHARK is not set # -# Archimedes/A5000 Implementations +# CLPS711X/EP721X Implementations # # -# Archimedes/A5000 Implementations (select only ONE) +# Epxa10db # -# CONFIG_ARCH_ARC is not set -# CONFIG_ARCH_A5K is not set # # Footbridge Implementations # -# CONFIG_ARCH_CATS is not set -# CONFIG_ARCH_PERSONAL_SERVER is not set -# CONFIG_ARCH_EBSA285_ADDIN is not set -# CONFIG_ARCH_EBSA285_HOST is not set -# CONFIG_ARCH_NETWINDER is not set + +# +# IOP3xx Implementation Options +# +# CONFIG_ARCH_IOP310 is not set +# CONFIG_ARCH_IOP321 is not set + +# +# IOP3xx Chipset Features +# + +# +# Intel PXA250/210 Implementations +# # # SA11x0 Implementations # # CONFIG_SA1100_ASSABET is not set -# CONFIG_ASSABET_NEPONSET is not set # CONFIG_SA1100_ADSBITSY is not set # CONFIG_SA1100_BRUTUS is not set # CONFIG_SA1100_CERF is not set +# CONFIG_SA1100_H3100 is not set # CONFIG_SA1100_H3600 is not set +# CONFIG_SA1100_H3800 is not set # CONFIG_SA1100_EXTENEX1 is not set # CONFIG_SA1100_FLEXANET is not set # CONFIG_SA1100_FREEBIRD is not set # CONFIG_SA1100_GRAPHICSCLIENT is not set # CONFIG_SA1100_GRAPHICSMASTER is not set +# CONFIG_SA1100_BADGE4 is not set # CONFIG_SA1100_JORNADA720 is not set +# CONFIG_SA1100_HACKKIT is not set # CONFIG_SA1100_HUW_WEBPANEL is not set # CONFIG_SA1100_ITSY is not set CONFIG_SA1100_LART=y @@ -79,76 +110,72 @@ CONFIG_SA1100_LART=y # CONFIG_SA1100_OMNIMETER is not set # CONFIG_SA1100_PANGOLIN is not set # CONFIG_SA1100_PLEB is not set +# CONFIG_SA1100_PT_SYSTEM3 is not set +# CONFIG_SA1100_SHANNON is not set # CONFIG_SA1100_SHERMAN is not set # CONFIG_SA1100_SIMPAD is not set # CONFIG_SA1100_PFS168 is not set # CONFIG_SA1100_VICTOR is not set # CONFIG_SA1100_XP860 is not set # CONFIG_SA1100_YOPY is not set +# CONFIG_SA1100_STORK is not set +# CONFIG_SA1100_SSP is not set CONFIG_SA1100_USB=m CONFIG_SA1100_USB_NETLINK=m CONFIG_SA1100_USB_CHAR=m # -# CLPS711X/EP721X Implementations +# Processor Type # -# CONFIG_ARCH_CDB89712 is not set -# CONFIG_ARCH_CLEP7312 is not set -# CONFIG_ARCH_EDB7211 is not set -# CONFIG_ARCH_P720T is not set -# CONFIG_ARCH_EP7211 is not set -# CONFIG_ARCH_EP7212 is not set -# CONFIG_ARCH_ACORN is not set -# CONFIG_FOOTBRIDGE is not set -# CONFIG_FOOTBRIDGE_HOST is not set -# CONFIG_FOOTBRIDGE_ADDIN is not set CONFIG_CPU_32=y -# CONFIG_CPU_26 is not set +CONFIG_CPU_SA1100=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_TLB_V4WB=y +CONFIG_CPU_MINICACHE=y # -# Processor Type +# Processor Features # -# CONFIG_CPU_32v3 is not set -CONFIG_CPU_32v4=y -# CONFIG_CPU_ARM610 is not set -# CONFIG_CPU_ARM710 is not set -# CONFIG_CPU_ARM720T is not set -# CONFIG_CPU_ARM920T is not set -# CONFIG_CPU_ARM1020 is not set -# CONFIG_CPU_SA110 is not set -CONFIG_CPU_SA1100=y -CONFIG_DISCONTIGMEM=y -# CONFIG_CPU_BIG_ENDIAN is not set # # General setup # -# CONFIG_PCI is not set -# CONFIG_ISA is not set -# CONFIG_ISA_DMA is not set +CONFIG_DISCONTIGMEM=y +CONFIG_ISA=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_SA1100=y +# CONFIG_CPU_FREQ_PROC_INTF is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_24_API=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_NET=y -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y # # At least one math emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y # CONFIG_BINFMT_MISC is not set + +# +# Generic Driver Options +# CONFIG_PM=y +# CONFIG_PREEMPT is not set CONFIG_APM=m # CONFIG_ARTHUR is not set CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram" -# CONFIG_PFS168_CMDLINE is not set CONFIG_LEDS=y # CONFIG_LEDS_TIMER is not set CONFIG_LEDS_CPU=y @@ -166,8 +193,9 @@ CONFIG_MTD=y CONFIG_MTD_DEBUG=y CONFIG_MTD_DEBUG_VERBOSE=1 CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set # CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_BOOTLDR_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set # CONFIG_MTD_AFS_PARTS is not set # @@ -177,51 +205,26 @@ CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set +# CONFIG_INFTL is not set # # RAM/ROM/Flash chip drivers # # CONFIG_MTD_CFI is not set -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDECPROBE is not set # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set -# CONFIG_MTD_JEDEC is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_SUN_UFLASH is not set -# CONFIG_MTD_NORA is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_RPXLITE is not set -# CONFIG_MTD_TQM8XXL is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_DBOX2 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_OCELOT is not set -# CONFIG_MTD_L440GX is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_CDB89712 is not set -# CONFIG_MTD_SA1100 is not set -# CONFIG_MTD_DC21285 is not set -# CONFIG_MTD_IQ80310 is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # # Self-contained MTD device drivers # -# CONFIG_MTD_PMC551 is not set # CONFIG_MTD_SLRAM is not set CONFIG_MTD_LART=y # CONFIG_MTD_MTDRAM is not set @@ -230,10 +233,9 @@ CONFIG_MTD_LART=y # # Disk-On-Chip Device Drivers # -# CONFIG_MTD_DOC1000 is not set # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set +# CONFIG_MTD_DOC2001PLUS is not set # # NAND Flash Device Drivers @@ -241,21 +243,15 @@ CONFIG_MTD_LART=y # CONFIG_MTD_NAND is not set # -# Plug and Play configuration +# Plug and Play support # # CONFIG_PNP is not set -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -266,44 +262,49 @@ CONFIG_BLK_DEV_INITRD=y # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=m # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set +# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set CONFIG_INET_ECN=y CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_NETFILTER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -316,8 +317,9 @@ CONFIG_SYN_COOKIES=y # CONFIG_NET_SCHED is not set # -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -333,15 +335,14 @@ CONFIG_DUMMY=m # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set +# CONFIG_MII is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set # CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set @@ -349,16 +350,10 @@ CONFIG_NET_ETHERNET=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set # CONFIG_PPP_FILTER is not set @@ -381,8 +376,6 @@ CONFIG_SLIP_COMPRESSED=y # Token Ring devices # # CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -407,10 +400,9 @@ CONFIG_IRLAN=m CONFIG_IRNET=m CONFIG_IRCOMM=m # CONFIG_IRDA_ULTRA is not set -CONFIG_IRDA_OPTIONS=y # -# IrDA options +# IrDA options # CONFIG_IRDA_CACHE_LAST_LSAP=y # CONFIG_IRDA_FAST_RR is not set @@ -424,132 +416,145 @@ CONFIG_IRDA_DEBUG=y # SIR device drivers # # CONFIG_IRTTY_SIR is not set -# CONFIG_IRPORT_SIR is not set # # Dongle support # -# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# # # FIR device drivers # -# CONFIG_USB_IRDA is not set # CONFIG_NSC_FIR is not set # CONFIG_WINBOND_FIR is not set # CONFIG_TOSHIBA_FIR is not set # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set -# CONFIG_VLSI_FIR is not set CONFIG_SA1100_FIR=m +# CONFIG_VIA_FIR is not set # -# ATA/IDE/MFM/RLL support +# Bluetooth support # -CONFIG_IDE=m +# CONFIG_BT is not set # -# IDE, ATA and ATAPI Block devices +# ATA/ATAPI/MFM/RLL support # +CONFIG_IDE=m CONFIG_BLK_DEV_IDE=m # # Please see Documentation/ide.txt for help/info on IDE drives # -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set CONFIG_BLK_DEV_IDEDISK=m # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=m # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IDE_TASKFILE_IO is not set # # IDE chipset support/bugfixes # -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set # CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # # CONFIG_SCSI is not set # # I2O device support # -# CONFIG_I2O is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Input device support +# +CONFIG_INPUT=y # -# Input core support +# Userland interfaces # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_PS2_SYNAPTICS is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # -# CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # -# CONFIG_SERIAL_ANAKIN is not set -# CONFIG_SERIAL_ANAKIN_CONSOLE is not set -# CONFIG_SERIAL_AMBA is not set -# CONFIG_SERIAL_AMBA_CONSOLE is not set -# CONFIG_SERIAL_CLPS711X is not set -# CONFIG_SERIAL_CLPS711X_CONSOLE is not set -# CONFIG_SERIAL_21285 is not set -# CONFIG_SERIAL_21285_OLD is not set -# CONFIG_SERIAL_21285_CONSOLE is not set +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# CONFIG_SERIAL_SA1100=y CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_SA1100_DEFAULT_BAUDRATE=9600 -# CONFIG_SERIAL_8250 is not set -# CONFIG_SERIAL_8250_CONSOLE is not set -# CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_MANY_PORTS is not set -# CONFIG_SERIAL_8250_SHARE_IRQ is not set -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_HUB6 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 -CONFIG_UCB1200=m -CONFIG_TOUCHSCREEN_UCB1200=m -CONFIG_AUDIO_UCB1200=m -CONFIG_ADC_UCB1200=m -# CONFIG_TOUCHSCREEN_H3600 is not set -CONFIG_PROFILER=m -# CONFIG_PFS168_SPI is not set -# CONFIG_PFS168_DTMF is not set -# CONFIG_PFS168_MISC is not set # # I2C support @@ -557,55 +562,39 @@ CONFIG_PROFILER=m # CONFIG_I2C is not set # -# L3 serial bus support +# I2C Algorithms # -# CONFIG_L3 is not set -# CONFIG_L3_ALGOBIT is not set -# CONFIG_L3_BIT_SA1100_GPIO is not set # -# Other L3 adapters +# I2C Hardware Bus support # -# CONFIG_L3_SA1111 is not set # -# L3 driver support +# I2C Hardware Sensors Chip support # -# CONFIG_L3_DRV_UDA1341 is not set -# CONFIG_BIT_SA1100_GPIO is not set +# CONFIG_I2C_SENSOR is not set # # Mice # # CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_SA1100_RTC=m +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -613,6 +602,7 @@ CONFIG_SA1100_RTC=m # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set # # Multimedia devices @@ -620,87 +610,104 @@ CONFIG_SA1100_RTC=m # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -CONFIG_EXT3_FS=m -CONFIG_JBD=m -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=m CONFIG_JFFS2_FS_DEBUG=1 +# CONFIG_JFFS2_FS_NAND is not set CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=m -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -CONFIG_UDF_FS=m -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=m CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set +# CONFIG_NFS_V4 is not set CONFIG_NFSD=m CONFIG_NFSD_V3=y -CONFIG_SUNRPC=m +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set CONFIG_LOCKD=m CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=m +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -728,6 +735,7 @@ CONFIG_NLS_CODEPAGE_850=m # 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_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set @@ -745,149 +753,62 @@ CONFIG_NLS_ISO8859_15=m CONFIG_NLS_UTF8=m # -# Sound -# -CONFIG_SOUND=m -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_MAESTRO3 is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_RME96XX is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_MIDI_VIA82CXXX is not set -# CONFIG_SOUND_ASSABET_UDA1341 is not set -# CONFIG_SOUND_H3600_UDA1341 is not set -# CONFIG_SOUND_PANGOLIN_UDA1341 is not set -# CONFIG_SOUND_SA1111_UDA1341 is not set -CONFIG_SOUND_SA1100SSP=m -# CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_WAVEARTIST is not set -# CONFIG_SOUND_TVMIXER is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers +# Graphics support # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_FB is not set # -# USB Human Interface Devices (HID) +# Console display driver support # +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y # -# Input core support is needed for USB HID -# - -# -# USB Imaging devices +# Sound # -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +CONFIG_SOUND=m # -# USB Multimedia devices +# Advanced Linux Sound Architecture # +# CONFIG_SND is not set # -# Video4Linux support is needed for USB Multimedia device support +# Open Sound System # -# CONFIG_USB_DABUSB is not set +# CONFIG_SOUND_PRIME is not set # -# USB Network adaptors +# Misc devices # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set # -# USB port drivers +# USB support # -# CONFIG_USB_USS720 is not set +# CONFIG_USB_GADGET is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC 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_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Bluetooth support +# Cryptographic options # -# CONFIG_BT is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_INFO is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_NO_PGT_CACHE is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_DC21285_PORT is not set -# CONFIG_DEBUG_CLPS711X_UART2 is not set +CONFIG_CRC32=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -prauN linux-2.6.0-test7/arch/arm/kernel/armksyms.c wli-2.6.0-test7-bk5-36/arch/arm/kernel/armksyms.c --- linux-2.6.0-test7/arch/arm/kernel/armksyms.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/kernel/armksyms.c 2003-10-14 02:49:46.000000000 -0700 @@ -131,6 +131,7 @@ EXPORT_SYMBOL(fp_init); EXPORT_SYMBOL(__machine_arch_type); /* networking */ +EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_nocheck); EXPORT_SYMBOL(__csum_ipv6_magic); diff -prauN linux-2.6.0-test7/arch/arm/mach-clps7500/core.c wli-2.6.0-test7-bk5-36/arch/arm/mach-clps7500/core.c --- linux-2.6.0-test7/arch/arm/mach-clps7500/core.c 2003-10-08 12:24:14.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mach-clps7500/core.c 2003-10-14 02:49:46.000000000 -0700 @@ -187,10 +187,6 @@ static struct irqchip clps7500_no_chip = .unmask = cl7500_no_action, }; -static void no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL }; static void __init clps7500_init_irq(void) diff -prauN linux-2.6.0-test7/arch/arm/mach-integrator/lm.c wli-2.6.0-test7-bk5-36/arch/arm/mach-integrator/lm.c --- linux-2.6.0-test7/arch/arm/mach-integrator/lm.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mach-integrator/lm.c 2003-10-14 02:49:46.000000000 -0700 @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include @@ -90,3 +91,6 @@ int lm_device_register(struct lm_device } return ret; } + +EXPORT_SYMBOL(lm_driver_register); +EXPORT_SYMBOL(lm_driver_unregister); diff -prauN linux-2.6.0-test7/arch/arm/mach-sa1100/cpu-sa1100.c wli-2.6.0-test7-bk5-36/arch/arm/mach-sa1100/cpu-sa1100.c --- linux-2.6.0-test7/arch/arm/mach-sa1100/cpu-sa1100.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mach-sa1100/cpu-sa1100.c 2003-10-14 02:49:46.000000000 -0700 @@ -194,7 +194,7 @@ static int sa1100_target(struct cpufreq_ new_ppcr = sa11x0_freq_to_ppcr(target_freq); if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) && (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min)) - mew_ppcr--; + new_ppcr--; break; } diff -prauN linux-2.6.0-test7/arch/arm/mach-sa1100/lart.c wli-2.6.0-test7-bk5-36/arch/arm/mach-sa1100/lart.c --- linux-2.6.0-test7/arch/arm/mach-sa1100/lart.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mach-sa1100/lart.c 2003-10-14 02:49:46.000000000 -0700 @@ -8,6 +8,7 @@ #include #include +#include #include #include diff -prauN linux-2.6.0-test7/arch/arm/mm/consistent.c wli-2.6.0-test7-bk5-36/arch/arm/mm/consistent.c --- linux-2.6.0-test7/arch/arm/mm/consistent.c 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mm/consistent.c 2003-10-14 02:53:51.000000000 -0700 @@ -327,7 +327,7 @@ static int __init consistent_init(void) do { pgd = pgd_offset(&init_mm, CONSISTENT_BASE); - pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); + pmd = pmd_alloc_kernel(&init_mm, pgd, CONSISTENT_BASE); if (!pmd) { printk(KERN_ERR "consistent_init: no pmd tables\n"); ret = -ENOMEM; diff -prauN linux-2.6.0-test7/arch/arm/mm/fault-armv.c wli-2.6.0-test7-bk5-36/arch/arm/mm/fault-armv.c --- linux-2.6.0-test7/arch/arm/mm/fault-armv.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mm/fault-armv.c 2003-10-14 03:01:39.000000000 -0700 @@ -191,19 +191,22 @@ void __flush_dcache_page(struct page *pa __cpuc_flush_dcache_page(page_address(page)); - if (!page->mapping) + if (!page_mapping(page)) return; /* * With a VIVT cache, we need to also write back * and invalidate any user data. */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each_rcu(l, &page_mapping(page)->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; mpnt = list_entry(l, struct vm_area_struct, shared); + if (mpnt->vm_flags & VM_DEAD) + continue; + /* * If this VMA is not in our MM, we can ignore it. */ @@ -234,12 +237,15 @@ make_coherent(struct vm_area_struct *vma * space, then we need to handle them specially to maintain * cache coherency. */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each_rcu(l, &page_mapping(page)->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; mpnt = list_entry(l, struct vm_area_struct, shared); + if (mpnt->vm_flags & VM_DEAD) + continue; + /* * If this VMA is not in our MM, we can ignore it. * Note that we intentionally don't mask out the VMA @@ -292,7 +298,7 @@ void update_mmu_cache(struct vm_area_str if (!pfn_valid(pfn)) return; page = pfn_to_page(pfn); - if (page->mapping) { + if (page_mapping(page)) { int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); if (dirty) diff -prauN linux-2.6.0-test7/arch/arm/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/arm/mm/ioremap.c --- linux-2.6.0-test7/arch/arm/mm/ioremap.c 2003-10-08 12:24:16.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -95,7 +95,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/arm/mm/minicache.c wli-2.6.0-test7-bk5-36/arch/arm/mm/minicache.c --- linux-2.6.0-test7/arch/arm/mm/minicache.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mm/minicache.c 2003-10-14 02:53:51.000000000 -0700 @@ -59,7 +59,7 @@ static int __init minicache_init(void) spin_lock(&init_mm.page_table_lock); pgd = pgd_offset_k(minicache_address); - pmd = pmd_alloc(&init_mm, pgd, minicache_address); + pmd = pmd_alloc_kernel(&init_mm, pgd, minicache_address); if (!pmd) BUG(); minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); diff -prauN linux-2.6.0-test7/arch/arm/mm/mm-armv.c wli-2.6.0-test7-bk5-36/arch/arm/mm/mm-armv.c --- linux-2.6.0-test7/arch/arm/mm/mm-armv.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm/mm/mm-armv.c 2003-10-14 02:53:51.000000000 -0700 @@ -132,7 +132,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm if (vectors_base() == 0) { /* - * This lock is here just to satisfy pmd_alloc and pte_lock + * This lock is here just to satisfy pmd_alloc_map() and pte_lock */ spin_lock(&mm->page_table_lock); @@ -140,20 +140,22 @@ pgd_t *get_pgd_slow(struct mm_struct *mm * On ARM, first page must always be allocated since it * contains the machine vectors. */ - new_pmd = pmd_alloc(mm, new_pgd, 0); + new_pmd = pmd_alloc_map(mm, new_pgd, 0); if (!new_pmd) goto no_pmd; - new_pte = pte_alloc_map(mm, new_pmd, 0); - if (!new_pte) + new_pte = pte_alloc_map(mm, new_pgd, &new_pmd, 0); + if (!new_pte) { + pmd_unmap(new_pmd); goto no_pte; + } init_pmd = pmd_offset(init_pgd, 0); init_pte = pte_offset_map_nested(init_pmd, 0); set_pte(new_pte, *init_pte); pte_unmap_nested(init_pte); pte_unmap(new_pte); - + pmd_unmap(new_pmd); spin_unlock(&mm->page_table_lock); } diff -prauN linux-2.6.0-test7/arch/arm26/mm/mm-memc.c wli-2.6.0-test7-bk5-36/arch/arm26/mm/mm-memc.c --- linux-2.6.0-test7/arch/arm26/mm/mm-memc.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/arm26/mm/mm-memc.c 2003-10-14 02:53:51.000000000 -0700 @@ -79,7 +79,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm goto no_pgd; /* - * This lock is here just to satisfy pmd_alloc and pte_lock + * This lock is here just to satisfy pmd_alloc_kernel() and pte_lock * FIXME: I bet we could avoid taking it pretty much altogether */ spin_lock(&mm->page_table_lock); @@ -88,7 +88,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm * On ARM, first page must always be allocated since it contains * the machine vectors. */ - new_pmd = pmd_alloc(mm, new_pgd, 0); + new_pmd = pmd_alloc_kernel(mm, new_pgd, 0); if (!new_pmd) goto no_pmd; diff -prauN linux-2.6.0-test7/arch/cris/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/cris/mm/ioremap.c --- linux-2.6.0-test7/arch/cris/mm/ioremap.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/cris/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -78,7 +78,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/i386/Kconfig wli-2.6.0-test7-bk5-36/arch/i386/Kconfig --- linux-2.6.0-test7/arch/i386/Kconfig 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/Kconfig 2003-10-14 03:05:27.000000000 -0700 @@ -397,6 +397,11 @@ config X86_OOSTORE depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 default y +config X86_CMOV + bool + depends on M686 || MPENTIUMII || MPENTIUMIII || MPENTIUM4 || MK8 || MCRUSOE + default y + config HPET_TIMER bool "HPET Timer Support" help @@ -725,6 +730,26 @@ config HIGHPTE low memory. Setting this option will put user-space page table entries in high memory. +config HIGHPMD + bool "Allocate 2nd-level pagetables from highmem" + depends on HIGHMEM64G && HIGHPTE + help + The VM uses one lowmem-allocated pmd entry for each pagetable + page of physical memory allocated, and preallocates them all + for 12KB of per-process lowmem overhead. For systems with + extreme amounts of highmem, this cannot be tolerated. Setting + this option will put userspace 2nd-level pagetables in highmem. + +config 4K_STACK + bool "Use smaller 4k per-task stacks" + help + This option will shrink the kernel's per-task stack from 8k to + 4k. This will greatly increase your chance of overflowing it. + But, if you use the per-cpu interrupt stacks as well, your chances + go way down. Also try the CONFIG_X86_STACK_CHECK overflow + detection. It is much more reliable than the currently in-kernel + version. + config MATH_EMULATION bool "Math emulation" ---help--- @@ -1217,6 +1242,34 @@ config FRAME_POINTER If you don't debug the kernel, you can say N, but we may not be able to solve problems without frame pointers. +config X86_STACK_CHECK + bool "Detect stack overflows" + depends on FRAME_POINTER + help + Say Y here to have the kernel attempt to detect when the per-task + kernel stack overflows. This is much more robust checking than + the above overflow check, which will only occasionally detect + an overflow. The level of guarantee here is much greater. + + Some older versions of gcc don't handle the -p option correctly. + Kernprof is affected by the same problem, which is described here: + http://oss.sgi.com/projects/kernprof/faq.html#Q9 + + Basically, if you get oopses in __free_pages_ok during boot when + you have this turned on, you need to fix gcc. The Redhat 2.96 + version and gcc-3.x seem to work. + + If not debugging a stack overflow problem, say N + +config MMAP_TOPDOWN + bool "Top-down vma allocation" + help + Say Y here to have the kernel change its vma allocation policy + to allocate vma's from the top of the address space down, and + to shove the stack low so as to conserve virtualspace. This is + risky because various apps, including a number of versions of + ld.so, depend on the kernel's bottom-up behavior. + config X86_EXTRA_IRQS bool depends on X86_LOCAL_APIC || X86_VOYAGER diff -prauN linux-2.6.0-test7/arch/i386/Makefile wli-2.6.0-test7-bk5-36/arch/i386/Makefile --- linux-2.6.0-test7/arch/i386/Makefile 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/Makefile 2003-10-14 02:59:53.000000000 -0700 @@ -84,6 +84,10 @@ mcore-$(CONFIG_X86_ES7000) := mach-es700 # default subarch .h files mflags-y += -Iinclude/asm-i386/mach-default +ifdef CONFIG_X86_STACK_CHECK +CFLAGS += -p +endif + head-y := arch/i386/kernel/head.o arch/i386/kernel/init_task.o libs-y += arch/i386/lib/ diff -prauN linux-2.6.0-test7/arch/i386/boot/compressed/misc.c wli-2.6.0-test7-bk5-36/arch/i386/boot/compressed/misc.c --- linux-2.6.0-test7/arch/i386/boot/compressed/misc.c 2003-10-08 12:24:15.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/boot/compressed/misc.c 2003-10-14 02:59:53.000000000 -0700 @@ -379,3 +379,7 @@ asmlinkage int decompress_kernel(struct if (high_loaded) close_output_buffer_if_we_run_high(mv); return high_loaded; } + +/* We don't actually check for stack overflows this early. */ +__asm__(".globl mcount ; mcount: ret\n"); + diff -prauN linux-2.6.0-test7/arch/i386/kernel/acpi/wakeup.S wli-2.6.0-test7-bk5-36/arch/i386/kernel/acpi/wakeup.S --- linux-2.6.0-test7/arch/i386/kernel/acpi/wakeup.S 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/acpi/wakeup.S 2003-10-14 02:49:46.000000000 -0700 @@ -172,14 +172,13 @@ ENTRY(wakeup_end) .org 0x1000 wakeup_pmode_return: - movl $__KERNEL_DS, %eax - movl %eax, %ds - movw $0x0e00 + 'u', %ds:(0xb8016) - - # restore other segment registers - xorl %eax, %eax + movw $__KERNEL_DS, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es movw %ax, %fs movw %ax, %gs + movw $0x0e00 + 'u', 0xb8016 # reload the gdt, as we need the full 32 bit address lgdt saved_gdt @@ -192,46 +191,30 @@ wakeup_pmode_return: wbinvd # and restore the stack ... but you need gdt for this to work - movl $__KERNEL_DS, %eax - movw %ax, %ss - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movl saved_esp, %esp + movl saved_context_esp, %esp - movw $0x0e00 + 'W', %ds:(0xb8018) - movl $(1024*1024*3), %ecx - movl $0, %esi - rep lodsb - movw $0x0e00 + 'O', %ds:(0xb8018) + movw $0x0e00 + 'W', 0xb8018 + outl %eax, $0x80 + outl %eax, $0x80 + movw $0x0e00 + 'O', 0xb8018 movl %cs:saved_magic, %eax cmpl $0x12345678, %eax jne bogus_magic - # restore the other general registers - movl saved_ebx, %ebx - movl saved_edi, %edi - movl saved_esi, %esi - movl saved_ebp, %ebp - # jump to place where we left off movl saved_eip,%eax - movw $0x0e00 + 'x', %ds:(0xb8018) - pushl %eax - popl %eax - movw $0x0e00 + '!', %ds:(0xb801a) + movw $0x0e00 + 'x', 0xb8018 + outl %eax, $0x80 + outl %eax, $0x80 + movw $0x0e00 + '!', 0xb801a jmp *%eax bogus_magic: - movw $0x0e00 + 'B', %ds:(0xb8018) - jmp bogus_magic + movw $0x0e00 + 'B', 0xb8018 + jmp bogus_magic + -bogus_magic2: - movw $0x0e00 + '2', %ds:(0xb8018) - jmp bogus_magic2 - ## # acpi_copy_wakeup_routine # @@ -267,80 +250,45 @@ ENTRY(acpi_copy_wakeup_routine) .data ALIGN -ENTRY(saved_ebp) .long 0 -ENTRY(saved_esi) .long 0 -ENTRY(saved_edi) .long 0 -ENTRY(saved_ebx) .long 0 - -ENTRY(saved_eip) .long 0 -ENTRY(saved_esp) .long 0 - ENTRY(saved_magic) .long 0 +ENTRY(saved_eip) .long 0 -ENTRY(do_suspend_lowlevel) - cmpl $0,4(%esp) - jne ret_point - call save_processor_state - - movl %esp, saved_context_esp - movl %eax, saved_context_eax +save_registers: + leal 4(%esp), %eax + movl %eax, saved_context_esp movl %ebx, saved_context_ebx - movl %ecx, saved_context_ecx - movl %edx, saved_context_edx movl %ebp, saved_context_ebp movl %esi, saved_context_esi movl %edi, saved_context_edi pushfl ; popl saved_context_eflags movl $ret_point,saved_eip - movl %esp,saved_esp - movl %ebp,saved_ebp - movl %ebx,saved_ebx - movl %edi,saved_edi - movl %esi,saved_esi - - pushl $3 - call acpi_enter_sleep_state - addl $4,%esp ret - .p2align 4,,7 -ret_point: - movl $__KERNEL_DS,%eax - movw %ax, %ds - movl saved_context_esp, %esp + + +restore_registers: movl saved_context_ebp, %ebp - movl saved_context_eax, %eax movl saved_context_ebx, %ebx - movl saved_context_ecx, %ecx - movl saved_context_edx, %edx movl saved_context_esi, %esi movl saved_context_edi, %edi - call restore_processor_state pushl saved_context_eflags ; popfl + ret + +ENTRY(do_suspend_lowlevel) + call save_processor_state + call save_registers + pushl $3 + call acpi_enter_sleep_state + ret + .p2align 4,,7 +ret_point: + call restore_registers + call restore_processor_state ret ENTRY(do_suspend_lowlevel_s4bios) - cmpl $0,4(%esp) - jne ret_point call save_processor_state - - movl %esp, saved_context_esp - movl %eax, saved_context_eax - movl %ebx, saved_context_ebx - movl %ecx, saved_context_ecx - movl %edx, saved_context_edx - movl %ebp, saved_context_ebp - movl %esi, saved_context_esi - movl %edi, saved_context_edi - pushfl ; popl saved_context_eflags - - movl $ret_point,saved_eip - movl %esp,saved_esp - movl %ebp,saved_ebp - movl %ebx,saved_ebx - movl %edi,saved_edi - movl %esi,saved_esi - + call save_registers call acpi_enter_sleep_state_s4bios ret diff -prauN linux-2.6.0-test7/arch/i386/kernel/apic.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/apic.c --- linux-2.6.0-test7/arch/i386/kernel/apic.c 2003-10-08 12:24:53.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/apic.c 2003-10-14 02:59:53.000000000 -0700 @@ -1069,7 +1069,8 @@ inline void smp_local_timer_interrupt(st * interrupt as well. Thus we cannot inline the local irq ... ] */ -void smp_apic_timer_interrupt(struct pt_regs regs) +struct pt_regs * IRQHANDLER(smp_apic_timer_interrupt(struct pt_regs* regs)); +struct pt_regs * smp_apic_timer_interrupt(struct pt_regs* regs) { int cpu = smp_processor_id(); @@ -1089,14 +1090,16 @@ void smp_apic_timer_interrupt(struct pt_ * interrupt lock, which is the WrongThing (tm) to do. */ irq_enter(); - smp_local_timer_interrupt(®s); + smp_local_timer_interrupt(regs); irq_exit(); + return regs; } /* * This interrupt should _never_ happen with our APIC/SMP architecture */ -asmlinkage void smp_spurious_interrupt(void) +struct pt_regs * IRQHANDLER(smp_spurious_interrupt(struct pt_regs* regs)); +struct pt_regs * smp_spurious_interrupt(struct pt_regs* regs) { unsigned long v; @@ -1114,13 +1117,15 @@ asmlinkage void smp_spurious_interrupt(v printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never happen.\n", smp_processor_id()); irq_exit(); + return regs; } /* * This interrupt should never happen with our APIC/SMP architecture */ -asmlinkage void smp_error_interrupt(void) +struct pt_regs * IRQHANDLER(smp_error_interrupt(struct pt_regs* regs)); +struct pt_regs * smp_error_interrupt(struct pt_regs* regs) { unsigned long v, v1; @@ -1145,6 +1150,7 @@ asmlinkage void smp_error_interrupt(void printk (KERN_INFO "APIC error on CPU%d: %02lx(%02lx)\n", smp_processor_id(), v , v1); irq_exit(); + return regs; } /* diff -prauN linux-2.6.0-test7/arch/i386/kernel/cpu/cpufreq/longhaul.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/cpu/cpufreq/longhaul.c --- linux-2.6.0-test7/arch/i386/kernel/cpu/cpufreq/longhaul.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/cpu/cpufreq/longhaul.c 2003-10-14 02:49:46.000000000 -0700 @@ -5,17 +5,14 @@ * Licensed under the terms of the GNU GPL License version 2. * Based upon datasheets & sample CPUs kindly provided by VIA. * - * VIA have currently 3 different versions of Longhaul. - * - * +---------------------+----------+---------------------------------+ - * | Marketing name | Codename | longhaul version / features. | - * +---------------------+----------+---------------------------------+ - * | Samuel/CyrixIII | C5A | v1 : multipliers only | - * | Samuel2/C3 | C3E/C5B | v1 : multiplier only | - * | Ezra | C5C | v2 : multipliers & voltage | - * | Ezra-T | C5M | v3 : multipliers, voltage & FSB | - * | Nehemiah | C5N | v3 : multipliers, voltage & FSB | - * +---------------------+----------+---------------------------------+ + * VIA have currently 2 different versions of Longhaul. + * Version 1 (Longhaul) uses the BCR2 MSR at 0x1147. + * It is present only in Samuel 1, Samuel 2 and Ezra. + * Version 2 (Powersaver) uses the POWERSAVER MSR at 0x110a. + * It is present in Ezra-T, Nehemiah and above. + * In addition to scaling multiplier, it can also scale voltage. + * There is provision for scaling FSB too, but this doesn't work + * too well in practice. * * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* */ @@ -66,7 +63,11 @@ static struct cpufreq_frequency_table *l static unsigned int calc_speed (int mult, int fsb) { - return ((mult/10)*fsb) + ((mult%10)*(fsb/2)); + int mhz; + mhz = (mult/10)*fsb; + if (mult%10) + mhz += fsb/2; + return mhz; } @@ -76,7 +77,7 @@ static int longhaul_get_cpu_mult (void) rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22; - if (longhaul_version==3) { + if (longhaul_version==2) { if (lo & (1<<27)) invalue+=16; } @@ -132,32 +133,15 @@ static void longhaul_setstate (unsigned break; /* - * Longhaul v2. (Ezra [C5C]) + * Powersaver. (Ezra-T [C5M], Nehemiah [C5N]) * We can scale voltage with this too, but that's currently * disabled until we come up with a decent 'match freq to voltage' * algorithm. * We also need to do the voltage/freq setting in order depending * on the direction of scaling (like we do in powernow-k7.c) - */ - case 2: - rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); - longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; - longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; - longhaul.bits.EnableSoftBusRatio = 1; - /* We must program the revision key only with values we - * know about, not blindly copy it from 0:3 */ - longhaul.bits.RevisionKey = 1; - wrmsrl (MSR_VIA_LONGHAUL, longhaul.val); - __hlt(); - - break; - - /* - * Longhaul v3. (Ezra-T [C5M], Nehemiah [C5N]) - * This can also do voltage scaling, but see above. * Ezra-T was alleged to do FSB scaling too, but it never worked in practice. */ - case 3: + case 2: rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf; longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; @@ -214,6 +198,7 @@ static int guess_fsb(int maxmult) static int __init longhaul_get_ranges (void) { + struct cpuinfo_x86 *c = cpu_data; unsigned long invalue; unsigned int minmult=0, maxmult=0; unsigned int multipliers[32]= { @@ -232,10 +217,13 @@ static int __init longhaul_get_ranges (v maxmult = longhaul_get_cpu_mult(); rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi); invalue = (lo & (1<<18|1<<19)) >>18; - fsb = eblcr_fsb_table[invalue]; + if (c->x86_model==6) + fsb = eblcr_fsb_table[invalue]; + else + fsb = guess_fsb(maxmult); break; - case 2 ... 3: + case 2: rdmsrl (MSR_VIA_LONGHAUL, longhaul.val); invalue = longhaul.bits.MaxMHzBR; @@ -378,10 +366,10 @@ static int longhaul_cpu_init (struct cpu break; case 7: /* C5B / C5C */ + longhaul_version=1; switch (c->x86_mask) { case 0: cpuname = "C3 'Samuel 2' [C5B]"; - longhaul_version=1; /* Note, this is not a typo, early Samuel2's had Samuel1 ratios. */ memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio)); memcpy (eblcr_table, samuel2_eblcr, sizeof(samuel2_eblcr)); @@ -391,7 +379,6 @@ static int longhaul_cpu_init (struct cpu cpuname = "C3 'Samuel 2' [C5B]"; else cpuname = "C3 'Ezra' [C5C]"; - longhaul_version=2; memcpy (clock_ratio, ezra_clock_ratio, sizeof(ezra_clock_ratio)); memcpy (eblcr_table, ezra_eblcr, sizeof(ezra_eblcr)); break; @@ -399,20 +386,21 @@ static int longhaul_cpu_init (struct cpu break; case 8: - cpuname = "C3 'Ezra-T [C5M]"; - longhaul_version=3; + cpuname = "C3 'Ezra-T' [C5M]"; + longhaul_version=2; numscales=32; memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio)); memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr)); break; - /* + case 9: cpuname = "C3 'Nehemiah' [C5N]"; - longhaul_version=3; + longhaul_version=2; numscales=32; memcpy (clock_ratio, nehemiah_clock_ratio, sizeof(nehemiah_clock_ratio)); memcpy (eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr)); - */ + break; + default: cpuname = "Unknown"; break; @@ -421,7 +409,7 @@ static int longhaul_cpu_init (struct cpu printk (KERN_INFO PFX "VIA %s CPU detected. Longhaul v%d supported.\n", cpuname, longhaul_version); - if ((longhaul_version==2 || longhaul_version==3) && (dont_scale_voltage==0)) + if ((longhaul_version==2) && (dont_scale_voltage==0)) longhaul_setup_voltagescaling(); ret = longhaul_get_ranges(); diff -prauN linux-2.6.0-test7/arch/i386/kernel/cpu/mcheck/p4.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/cpu/mcheck/p4.c --- linux-2.6.0-test7/arch/i386/kernel/cpu/mcheck/p4.c 2003-10-08 12:24:16.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/cpu/mcheck/p4.c 2003-10-14 02:59:53.000000000 -0700 @@ -61,11 +61,13 @@ static void intel_thermal_interrupt(stru /* Thermal interrupt handler for this CPU setup */ static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt; -asmlinkage void smp_thermal_interrupt(struct pt_regs regs) +struct pt_regs * IRQHANDLER(smp_thermal_interrupt(struct pt_regs* regs)); +struct pt_regs * smp_thermal_interrupt(struct pt_regs* regs) { irq_enter(); - vendor_thermal_interrupt(®s); + vendor_thermal_interrupt(regs); irq_exit(); + return regs; } /* P4/Xeon Thermal regulation detect and init */ diff -prauN linux-2.6.0-test7/arch/i386/kernel/entry.S wli-2.6.0-test7-bk5-36/arch/i386/kernel/entry.S --- linux-2.6.0-test7/arch/i386/kernel/entry.S 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/entry.S 2003-10-14 02:59:53.000000000 -0700 @@ -160,7 +160,7 @@ do_lcall: movl %eax,EFLAGS(%ebp) # movl %edx,EIP(%ebp) # Now we move them to their "normal" places movl %ecx,CS(%ebp) # - andl $-8192, %ebp # GET_THREAD_INFO + GET_THREAD_INFO_WITH_ESP(%ebp) # GET_THREAD_INFO movl TI_EXEC_DOMAIN(%ebp), %edx # Get the execution domain call *4(%edx) # Call the lcall7 handler for the domain addl $4, %esp @@ -394,17 +394,78 @@ ENTRY(irq_entries_start) vector=vector+1 .endr + +# lets play optimizing compiler... +#ifdef CONFIG_X86_CMOV +#define COND_MOVE cmovnz %esi,%esp; +#else +#define COND_MOVE \ + jz 1f; \ + mov %esi,%esp; \ +1: +#endif + +# These macros will switch you to, and from a per-cpu interrupt stack +# They take the pt_regs arg and move it from the normal place on the +# stack to %eax. Any handler function can retrieve it using regparm(1). +# The handlers are expected to return the stack to switch back to in +# the same register. +# +# This means that the irq handlers need to return their arg +# +# SWITCH_TO_IRQSTACK clobbers %ebx, %ecx, %edx, %esi +# old stack gets put in %eax + +.macro SWITCH_TO_IRQSTACK + GET_THREAD_INFO(%ebx); + movl TI_IRQ_STACK(%ebx),%ecx; + movl TI_TASK(%ebx),%edx; + movl %esp,%eax; + + # %ecx+THREAD_SIZE is next stack -4 keeps us in the right one + leal (THREAD_SIZE-4)(%ecx),%esi; + + # is there a valid irq_stack? + testl %ecx,%ecx; + COND_MOVE; + + # update the task pointer in the irq stack + GET_THREAD_INFO(%esi); + movl %edx,TI_TASK(%esi); + + # update the preempt count in the irq stack + movl TI_PRE_COUNT(%ebx),%ecx; + movl %ecx,TI_PRE_COUNT(%esi); +.endm + +# copy flags from the irq stack back into the task's thread_info +# %esi is saved over the irq handler call and contains the irq stack's +# thread_info pointer +# %eax was returned from the handler, as described above +# %ebx contains the original thread_info pointer + +.macro RESTORE_FROM_IRQSTACK + movl %eax,%esp; + movl TI_FLAGS(%esi),%eax; + movl $0,TI_FLAGS(%esi); + LOCK orl %eax,TI_FLAGS(%ebx); +.endm + ALIGN common_interrupt: SAVE_ALL + SWITCH_TO_IRQSTACK call do_IRQ + RESTORE_FROM_IRQSTACK jmp ret_from_intr #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ pushl $nr-256; \ SAVE_ALL \ - call smp_/**/name; \ + SWITCH_TO_IRQSTACK; \ + call smp_/**/name; \ + RESTORE_FROM_IRQSTACK; \ jmp ret_from_intr; /* The include is where all of the SMP etc. interrupts come from */ @@ -604,6 +665,61 @@ ENTRY(spurious_interrupt_bug) pushl $do_spurious_interrupt_bug jmp error_code + +#ifdef CONFIG_X86_STACK_CHECK +.data + .globl stack_overflowed +stack_overflowed: + .long 0 +.text + +ENTRY(mcount) + push %eax + movl $(THREAD_SIZE - 1),%eax + andl %esp,%eax + cmpl $STACK_WARN,%eax /* more than half the stack is used*/ + jle 1f +2: + popl %eax + ret +1: + lock; btsl $0,stack_overflowed + jc 2b + + # switch to overflow stack + movl %esp,%eax + movl $(stack_overflow_stack + THREAD_SIZE - 4),%esp + + pushf + cli + pushl %eax + + # push eip then esp of error for stack_overflow_panic + pushl 4(%eax) + pushl %eax + + # update the task pointer and cpu in the overflow stack's thread_info. + GET_THREAD_INFO_WITH_ESP(%eax) + movl TI_TASK(%eax),%ebx + movl %ebx,stack_overflow_stack+TI_TASK + movl TI_CPU(%eax),%ebx + movl %ebx,stack_overflow_stack+TI_CPU + + call stack_overflow + + # pop off call arguments + addl $8,%esp + + popl %eax + popf + movl %eax,%esp + popl %eax + movl $0,stack_overflowed + ret + +#warning stack check enabled +#endif + .data ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ diff -prauN linux-2.6.0-test7/arch/i386/kernel/head.S wli-2.6.0-test7-bk5-36/arch/i386/kernel/head.S --- linux-2.6.0-test7/arch/i386/kernel/head.S 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/head.S 2003-10-14 02:59:53.000000000 -0700 @@ -16,6 +16,7 @@ #include #include #include +#include #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F @@ -325,7 +326,7 @@ rp_sidt: ret ENTRY(stack_start) - .long init_thread_union+8192 + .long init_thread_union+THREAD_SIZE .long __BOOT_DS /* This is the default interrupt "handler" :-) */ diff -prauN linux-2.6.0-test7/arch/i386/kernel/i386_ksyms.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/i386_ksyms.c --- linux-2.6.0-test7/arch/i386/kernel/i386_ksyms.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/i386_ksyms.c 2003-10-14 20:13:26.000000000 -0700 @@ -186,23 +186,11 @@ extern void * memcpy(void *,const void * EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); -#ifdef CONFIG_HAVE_DEC_LOCK -EXPORT_SYMBOL(atomic_dec_and_lock); -#endif - extern int is_sony_vaio_laptop; EXPORT_SYMBOL(is_sony_vaio_laptop); EXPORT_SYMBOL(__PAGE_KERNEL); -#ifdef CONFIG_HIGHMEM -EXPORT_SYMBOL(kmap); -EXPORT_SYMBOL(kunmap); -EXPORT_SYMBOL(kmap_atomic); -EXPORT_SYMBOL(kunmap_atomic); -EXPORT_SYMBOL(kmap_atomic_to_page); -#endif - #ifdef CONFIG_EDD_MODULE EXPORT_SYMBOL(edd); EXPORT_SYMBOL(eddnr); @@ -212,4 +200,9 @@ EXPORT_SYMBOL(eddnr); EXPORT_SYMBOL(ist_info); #endif +#ifdef CONFIG_X86_STACK_CHECK +void mcount(void); +EXPORT_SYMBOL(mcount); +#endif + EXPORT_SYMBOL(csum_partial); diff -prauN linux-2.6.0-test7/arch/i386/kernel/init_task.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/init_task.c --- linux-2.6.0-test7/arch/i386/kernel/init_task.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/init_task.c 2003-10-14 02:59:53.000000000 -0700 @@ -17,6 +17,14 @@ struct mm_struct init_mm = INIT_MM(init_ EXPORT_SYMBOL(init_mm); +union thread_union init_irq_union + __attribute__((__section__(".data.init_task"))); + +#ifdef CONFIG_X86_STACK_CHECK +union thread_union stack_overflow_stack + __attribute__((__section__(".data.init_task"))); +#endif + /* * Initial thread structure. * diff -prauN linux-2.6.0-test7/arch/i386/kernel/irq.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/irq.c --- linux-2.6.0-test7/arch/i386/kernel/irq.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/irq.c 2003-10-14 02:59:53.000000000 -0700 @@ -355,8 +355,10 @@ inline void disable_irq_nosync(unsigned void disable_irq(unsigned int irq) { + irq_desc_t *desc = irq_desc + irq; disable_irq_nosync(irq); - synchronize_irq(irq); + if (desc->action) + synchronize_irq(irq); } /** @@ -378,7 +380,7 @@ void enable_irq(unsigned int irq) spin_lock_irqsave(&desc->lock, flags); switch (desc->depth) { case 1: { - unsigned int status = desc->status & ~IRQ_DISABLED; + unsigned int status = desc->status & ~(IRQ_DISABLED | IRQ_INPROGRESS); desc->status = status; if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { desc->status = status | IRQ_REPLAY; @@ -402,7 +404,8 @@ void enable_irq(unsigned int irq) * SMP cross-CPU interrupts have their own specific * handlers). */ -asmlinkage unsigned int do_IRQ(struct pt_regs regs) +struct pt_regs * IRQHANDLER(do_IRQ(struct pt_regs *regs)); +struct pt_regs * do_IRQ(struct pt_regs *regs) { /* * We ack quickly, we don't want the irq controller @@ -414,7 +417,7 @@ asmlinkage unsigned int do_IRQ(struct pt * 0 return value means that this irq is already being * handled by some other CPU. (or is disabled) */ - int irq = regs.orig_eax & 0xff; /* high bits used in ret_from_ code */ + int irq = regs->orig_eax & 0xff; /* high bits used in ret_from_ code */ irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; @@ -427,7 +430,7 @@ asmlinkage unsigned int do_IRQ(struct pt long esp; __asm__ __volatile__("andl %%esp,%0" : - "=r" (esp) : "0" (8191)); + "=r" (esp) : "0" (THREAD_SIZE - 1)); if (unlikely(esp < (sizeof(struct thread_info) + 1024))) { printk("do_IRQ: stack overflow: %ld\n", esp - sizeof(struct thread_info)); @@ -480,7 +483,7 @@ asmlinkage unsigned int do_IRQ(struct pt irqreturn_t action_ret; spin_unlock(&desc->lock); - action_ret = handle_IRQ_event(irq, ®s, action); + action_ret = handle_IRQ_event(irq, regs, action); spin_lock(&desc->lock); if (!noirqdebug) note_interrupt(irq, desc, action_ret); @@ -500,7 +503,7 @@ out: irq_exit(); - return 1; + return regs; } /** diff -prauN linux-2.6.0-test7/arch/i386/kernel/mpparse.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/mpparse.c --- linux-2.6.0-test7/arch/i386/kernel/mpparse.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/mpparse.c 2003-10-14 20:54:07.000000000 -0700 @@ -337,6 +337,16 @@ static void __init smp_read_mpc_oem(stru } } } + +static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (strncmp(oem, "IBM NUMA", 8)) + printk("Warning! May not be a NUMA-Q system!\n"); + if (mpc->mpc_oemptr) + smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, + mpc->mpc_oemsize); +} #endif /* CONFIG_X86_NUMAQ */ /* diff -prauN linux-2.6.0-test7/arch/i386/kernel/process.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/process.c --- linux-2.6.0-test7/arch/i386/kernel/process.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/process.c 2003-10-14 02:59:53.000000000 -0700 @@ -213,7 +213,25 @@ static int __init idle_setup (char *str) __setup("idle=", idle_setup); -void show_regs(struct pt_regs * regs) +void stack_overflow(unsigned long esp, unsigned long eip) +{ + int panicing = ((esp&(THREAD_SIZE-1)) <= STACK_PANIC); + + printk( "esp: 0x%lx masked: 0x%lx STACK_PANIC:0x%lx %d %d\n", + esp, (esp&(THREAD_SIZE-1)), STACK_PANIC, (((esp&(THREAD_SIZE-1)) <= STACK_PANIC)), panicing ); + + if (panicing) + print_symbol("stack overflow from %s\n", eip); + else + print_symbol("excessive stack use from %s\n", eip); + printk("esp: %p\n", (void*)esp); + show_trace(NULL, (void*)esp); + + if (panicing) + panic("stack overflow\n"); +} + +asmlinkage void show_regs(struct pt_regs * regs) { unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; @@ -501,7 +519,7 @@ struct task_struct * __switch_to(struct struct tss_struct *tss = init_tss + cpu; /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ - + next_p->thread_info->irq_stack = prev_p->thread_info->irq_stack; __unlazy_fpu(prev_p); /* diff -prauN linux-2.6.0-test7/arch/i386/kernel/smp.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/smp.c --- linux-2.6.0-test7/arch/i386/kernel/smp.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/smp.c 2003-10-14 02:59:53.000000000 -0700 @@ -308,7 +308,8 @@ static inline void leave_mm (unsigned lo * 2) Leave the mm if we are in the lazy tlb mode. */ -asmlinkage void smp_invalidate_interrupt (void) +struct pt_regs * IRQHANDLER(smp_invalidate_interrupt(struct pt_regs *regs)); +struct pt_regs * smp_invalidate_interrupt(struct pt_regs *regs) { unsigned long cpu; @@ -340,6 +341,7 @@ asmlinkage void smp_invalidate_interrupt smp_mb__after_clear_bit(); out: put_cpu_no_resched(); + return regs; } static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, @@ -576,12 +578,15 @@ void smp_send_stop(void) * all the work is done automatically when * we return from the interrupt. */ -asmlinkage void smp_reschedule_interrupt(void) +struct pt_regs *IRQHANDLER(smp_reschedule_interrupt(struct pt_regs *)); +struct pt_regs *smp_reschedule_interrupt(struct pt_regs *regs) { ack_APIC_irq(); + return regs; } -asmlinkage void smp_call_function_interrupt(void) +struct pt_regs *IRQHANDLER(smp_call_function_interrupt(struct pt_regs *)); +struct pt_regs *smp_call_function_interrupt(struct pt_regs *regs) { void (*func) (void *info) = call_data->func; void *info = call_data->info; @@ -605,5 +610,6 @@ asmlinkage void smp_call_function_interr mb(); atomic_inc(&call_data->finished); } + return regs; } diff -prauN linux-2.6.0-test7/arch/i386/kernel/smpboot.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/smpboot.c --- linux-2.6.0-test7/arch/i386/kernel/smpboot.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/smpboot.c 2003-10-14 02:59:53.000000000 -0700 @@ -71,6 +71,11 @@ static cpumask_t smp_commenced_mask; /* Per CPU bogomips and other parameters */ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +/* Per CPU interrupt stacks */ +extern union thread_union init_irq_union; +union thread_union *irq_stacks[NR_CPUS] __cacheline_aligned = + { &init_irq_union, }; + /* Set when the idlers are all forked */ int smp_threads_ready; @@ -770,6 +775,24 @@ wakeup_secondary_cpu(int phys_apicid, un } #endif /* WAKE_SECONDARY_VIA_INIT */ +static void __init setup_irq_stack(task_t *task, int cpu) +{ + unsigned long stack; + + stack = __get_free_pages(GFP_KERNEL, THREAD_ORDER); + if (!task) + panic("Cannot allocate irq stack\n"); + irq_stacks[cpu] = (void *)stack; + memset(irq_stacks[cpu], 0, THREAD_SIZE); + irq_stacks[cpu]->thread_info.cpu = cpu; + irq_stacks[cpu]->thread_info.preempt_count = 1; + task->thread_info->irq_stack = &irq_stacks[cpu]->thread_info; + /* + * If we want to make the irq stack more than one unit + * deep, we can chain them off the irq_stack pointer here. + */ +} + extern cpumask_t cpu_initialized; static int __init do_boot_cpu(int apicid) @@ -793,6 +816,7 @@ static int __init do_boot_cpu(int apicid idle = fork_by_hand(); if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); + setup_irq_stack(idle, cpu); wake_up_forked_process(idle); /* diff -prauN linux-2.6.0-test7/arch/i386/kernel/timers/timer_tsc.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/timers/timer_tsc.c --- linux-2.6.0-test7/arch/i386/kernel/timers/timer_tsc.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/timers/timer_tsc.c 2003-10-14 02:49:46.000000000 -0700 @@ -321,7 +321,7 @@ time_cpufreq_notifier(struct notifier_bl { struct cpufreq_freqs *freq = data; - write_seqlock(&xtime_lock); + write_seqlock_irq(&xtime_lock); if (!ref_freq) { ref_freq = freq->old; loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; @@ -342,7 +342,7 @@ time_cpufreq_notifier(struct notifier_bl } #endif } - write_sequnlock(&xtime_lock); + write_sequnlock_irq(&xtime_lock); return 0; } diff -prauN linux-2.6.0-test7/arch/i386/kernel/traps.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/traps.c --- linux-2.6.0-test7/arch/i386/kernel/traps.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/traps.c 2003-10-14 02:49:46.000000000 -0700 @@ -104,7 +104,7 @@ void show_trace(struct task_struct *task #ifdef CONFIG_KALLSYMS printk("\n"); #endif - while (((long) stack & (THREAD_SIZE-1)) != 0) { + while (((long) stack & (THREAD_SIZE-4)) != 0) { addr = *stack++; if (kernel_text_address(addr)) { printk(" [<%08lx>] ", addr); @@ -138,7 +138,7 @@ void show_stack(struct task_struct *task stack = esp; for(i = 0; i < kstack_depth_to_print; i++) { - if (((long) stack & (THREAD_SIZE-1)) == 0) + if (((long) stack & (THREAD_SIZE-4)) == 0) break; if (i && ((i % 8) == 0)) printk("\n "); diff -prauN linux-2.6.0-test7/arch/i386/kernel/vm86.c wli-2.6.0-test7-bk5-36/arch/i386/kernel/vm86.c --- linux-2.6.0-test7/arch/i386/kernel/vm86.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/kernel/vm86.c 2003-10-14 02:58:33.000000000 -0700 @@ -127,16 +127,17 @@ struct pt_regs * save_v86_state(struct k return ret; } -static void mark_screen_rdonly(struct task_struct * tsk) +static void mark_screen_rdonly(task_t *task) { + struct mm_struct *mm = task->mm; pgd_t *pgd; pmd_t *pmd; pte_t *pte, *mapped; int i; preempt_disable(); - spin_lock(&tsk->mm->page_table_lock); - pgd = pgd_offset(tsk->mm, 0xA0000); + spin_lock(&mm->page_table_lock); + pgd = pgd_offset(mm, 0xA0000); if (pgd_none(*pgd)) goto out; if (pgd_bad(*pgd)) { @@ -144,23 +145,26 @@ static void mark_screen_rdonly(struct ta pgd_clear(pgd); goto out; } - pmd = pmd_offset(pgd, 0xA0000); - if (pmd_none(*pmd)) + pmd = pmd_offset_map(pgd, 0xA0000); + if (pmd_none(*pmd)) { + pmd_unmap(pmd); goto out; - if (pmd_bad(*pmd)) { + } else if (pmd_bad(*pmd)) { pmd_ERROR(*pmd); pmd_clear(pmd); + pmd_unmap(pmd); goto out; } pte = mapped = pte_offset_map(pmd, 0xA0000); for (i = 0; i < 32; i++) { if (pte_present(*pte)) - set_pte(pte, pte_wrprotect(*pte)); + vm_ptep_set_wrprotect(mm, pte); pte++; } pte_unmap(mapped); + pmd_unmap(pmd); out: - spin_unlock(&tsk->mm->page_table_lock); + spin_unlock(&mm->page_table_lock); preempt_enable(); flush_tlb(); } diff -prauN linux-2.6.0-test7/arch/i386/lib/dec_and_lock.c wli-2.6.0-test7-bk5-36/arch/i386/lib/dec_and_lock.c --- linux-2.6.0-test7/arch/i386/lib/dec_and_lock.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/lib/dec_and_lock.c 2003-10-14 20:04:08.000000000 -0700 @@ -8,6 +8,7 @@ */ #include +#include #include int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) @@ -38,3 +39,34 @@ slow_path: spin_unlock(lock); return 0; } +EXPORT_SYMBOL(atomic_dec_and_lock); + +int atomic_dec_and_bit_lock(atomic_t *atomic, int bit, unsigned long *word) +{ + int counter; + int newcount; + +repeat: + counter = atomic_read(atomic); + newcount = counter-1; + + if (!newcount) + goto slow_path; + + asm volatile("lock; cmpxchgl %1,%2" + :"=a" (newcount) + :"r" (newcount), "m" (atomic->counter), "0" (counter)); + + /* If the above failed, "eax" will have changed */ + if (newcount != counter) + goto repeat; + return 0; + +slow_path: + bit_spin_lock(bit, word); + if (atomic_dec_and_test(atomic)) + return 1; + bit_spin_unlock(bit, word); + return 0; +} +EXPORT_SYMBOL(atomic_dec_and_bit_lock); diff -prauN linux-2.6.0-test7/arch/i386/mm/discontig.c wli-2.6.0-test7-bk5-36/arch/i386/mm/discontig.c --- linux-2.6.0-test7/arch/i386/mm/discontig.c 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/discontig.c 2003-10-14 03:05:02.000000000 -0700 @@ -72,8 +72,6 @@ extern unsigned long max_low_pfn; extern unsigned long totalram_pages; extern unsigned long totalhigh_pages; -#define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE) - unsigned long node_remap_start_pfn[MAX_NUMNODES]; unsigned long node_remap_size[MAX_NUMNODES]; unsigned long node_remap_offset[MAX_NUMNODES]; @@ -128,6 +126,48 @@ static void __init find_max_pfn_node(int BUG(); } +extern char __per_cpu_start[], __per_cpu_end[]; +unsigned long __per_cpu_offset[NR_CPUS]; + +#define PER_CPU_PAGES PFN_UP((unsigned long)(__per_cpu_end-__per_cpu_start)) +#define MEM_MAP_SIZE(n) PFN_UP((node_end_pfn[n]-node_start_pfn[n]+1)*sizeof(struct page)) + +static void __init allocate_per_cpu_pages(int cpu) +{ + int cpu_in_node, node = cpu_to_node(cpu); + unsigned long vaddr; + cpumask_t nodemask = node_to_cpumask(node); + + if (!PER_CPU_PAGES || node >= numnodes) + return; + + if (!node) { + vaddr = (unsigned long)alloc_bootmem(PER_CPU_PAGES*PAGE_SIZE); + __per_cpu_offset[cpu] = vaddr - (unsigned long)__per_cpu_start; + } else { + int k; + vaddr = (unsigned long)node_remap_start_vaddr[node]; + for (k = 0, cpu_in_node = 0; k < cpu; ++k) + if (cpu_isset(k, nodemask)) + ++cpu_in_node; + __per_cpu_offset[cpu] = vaddr + PAGE_SIZE*MEM_MAP_SIZE(node) + + PAGE_SIZE*PFN_UP(sizeof(pg_data_t)) + + PAGE_SIZE*PER_CPU_PAGES*cpu_in_node + - (unsigned long)__per_cpu_start; + } + memcpy(RELOC_HIDE((char *)__per_cpu_start, __per_cpu_offset[cpu]), + __per_cpu_start, + PER_CPU_PAGES*PAGE_SIZE); +} + +void __init setup_per_cpu_areas(void) +{ + int cpu; + for (cpu = 0; cpu < NR_CPUS; ++cpu) + allocate_per_cpu_pages(cpu); +} + + /* * Allocate memory for the pg_data_t via a crude pre-bootmem method * We ought to relocate these onto their own node later on during boot. @@ -205,13 +245,11 @@ static unsigned long calculate_numa_rema unsigned long size, reserve_pages = 0; for (nid = 1; nid < numnodes; nid++) { - /* calculate the size of the mem_map needed in bytes */ - size = (node_end_pfn[nid] - node_start_pfn[nid] + 1) - * sizeof(struct page) + sizeof(pg_data_t); - /* convert size to large (pmd size) pages, rounding up */ - size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES; - /* now the roundup is correct, convert to PAGE_SIZE pages */ - size = size * PTRS_PER_PTE; + /* calculate the size of the mem_map needed in pages */ + size = MEM_MAP_SIZE(nid) + PFN_UP(sizeof(pg_data_t)) + + PER_CPU_PAGES*MAX_NODE_CPUS; + /* round up to nearest pmd boundary */ + size = (size + PTRS_PER_PTE - 1) & ~(PTRS_PER_PTE - 1); printk("Reserving %ld pages of KVA for lmem_map of node %d\n", size, nid); node_remap_size[nid] = size; diff -prauN linux-2.6.0-test7/arch/i386/mm/fault.c wli-2.6.0-test7-bk5-36/arch/i386/mm/fault.c --- linux-2.6.0-test7/arch/i386/mm/fault.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/fault.c 2003-10-14 02:53:51.000000000 -0700 @@ -19,6 +19,7 @@ #include #include #include /* For unblank_screen() */ +#include #include #include @@ -55,6 +56,147 @@ void bust_spinlocks(int yes) console_loglevel = loglevel_save; } +/* + * Return EIP plus the CS segment base. The segment limit is also + * adjusted, clamped to the kernel/user address space (whichever is + * appropriate), and returned in *eip_limit. + * + * The segment is checked, because it might have been changed by another + * task between the original faulting instruction and here. + * + * If CS is no longer a valid code segment, or if EIP is beyond the + * limit, or if it is a kernel address when CS is not a kernel segment, + * then the returned value will be greater than *eip_limit. + * + * This is slow, but is very rarely executed. + */ +static inline unsigned long get_segment_eip(struct pt_regs *regs, + unsigned long *eip_limit) +{ + unsigned long eip = regs->eip; + unsigned seg = regs->xcs & 0xffff; + u32 seg_ar, seg_limit, base, *desc; + + /* The standard kernel/user address space limit. */ + *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; + + /* Unlikely, but must come before segment checks. */ + if (unlikely((regs->eflags & VM_MASK) != 0)) + return eip + (seg << 4); + + /* By far the most common cases. */ + if (likely(seg == __USER_CS || seg == __KERNEL_CS)) + return eip; + + /* Check the segment exists, is within the current LDT/GDT size, + that kernel/user (ring 0..3) has the appropriate privilege, + that it's a code segment, and get the limit. */ + __asm__ ("larl %3,%0; lsll %3,%1" + : "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg)); + if ((~seg_ar & 0x9800) || eip > seg_limit) { + *eip_limit = 0; + return 1; /* So that returned eip > *eip_limit. */ + } + + /* Get the GDT/LDT descriptor base. + When you look for races in this code remember that + LDT and other horrors are only used in user space. */ + if (seg & (1<<2)) { + /* Must lock the LDT while reading it. */ + down(¤t->mm->context.sem); + desc = current->mm->context.ldt; + desc = (void *)desc + (seg & ~7); + } else { + /* Must disable preemption while reading the GDT. */ + desc = (u32 *)&cpu_gdt_table[get_cpu()]; + desc = (void *)desc + (seg & ~7); + } + + /* Decode the code segment base from the descriptor */ + base = (desc[0] >> 16) | + ((desc[1] & 0xff) << 16) | + (desc[1] & 0xff000000); + + if (seg & (1<<2)) { + up(¤t->mm->context.sem); + } else + put_cpu(); + + /* Adjust EIP and segment limit, and clamp at the kernel limit. + It's legitimate for segments to wrap at 0xffffffff. */ + seg_limit += base; + if (seg_limit < *eip_limit && seg_limit >= base) + *eip_limit = seg_limit; + return eip + base; +} + +/* + * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch. + * Check that here and ignore it. + */ +static int __is_prefetch(struct pt_regs *regs, unsigned long addr) +{ + unsigned long limit; + unsigned long instr = get_segment_eip (regs, &limit); + int scan_more = 1; + int prefetch = 0; + int i; + + for (i = 0; scan_more && i < 15; i++) { + unsigned char opcode; + unsigned char instr_hi; + unsigned char instr_lo; + + if (instr > limit) + break; + if (__get_user(opcode, (unsigned char *) instr)) + break; + + instr_hi = opcode & 0xf0; + instr_lo = opcode & 0x0f; + instr++; + + switch (instr_hi) { + case 0x20: + case 0x30: + /* Values 0x26,0x2E,0x36,0x3E are valid x86 prefixes. */ + scan_more = ((instr_lo & 7) == 0x6); + break; + + case 0x60: + /* 0x64 thru 0x67 are valid prefixes in all modes. */ + scan_more = (instr_lo & 0xC) == 0x4; + break; + case 0xF0: + /* 0xF0, 0xF2, and 0xF3 are valid prefixes */ + scan_more = !instr_lo || (instr_lo>>1) == 1; + break; + case 0x00: + /* Prefetch instruction is 0x0F0D or 0x0F18 */ + scan_more = 0; + if (instr > limit) + break; + if (__get_user(opcode, (unsigned char *) instr)) + break; + prefetch = (instr_lo == 0xF) && + (opcode == 0x0D || opcode == 0x18); + break; + default: + scan_more = 0; + break; + } + } + return prefetch; +} + +static inline int is_prefetch(struct pt_regs *regs, unsigned long addr) +{ + if (unlikely(boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 6)) + return __is_prefetch(regs, addr); + return 0; +} + asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); /* @@ -86,6 +228,8 @@ asmlinkage void do_page_fault(struct pt_ tsk = current; + info.si_code = SEGV_MAPERR; + /* * We fault-in kernel-space virtual memory on-demand. The * 'reference' page table is init_mm.pgd. @@ -99,18 +243,24 @@ asmlinkage void do_page_fault(struct pt_ * (error_code & 4) == 0, and that the fault was not a * protection error (error_code & 1) == 0. */ - if (address >= TASK_SIZE && !(error_code & 5)) - goto vmalloc_fault; + if (unlikely(address >= TASK_SIZE)) { + if (!(error_code & 5)) + goto vmalloc_fault; + /* + * Don't take the mm semaphore here. If we fixup a prefetch + * fault we could otherwise deadlock. + */ + goto bad_area_nosemaphore; + } mm = tsk->mm; - info.si_code = SEGV_MAPERR; /* * If we're in an interrupt, have no user context or are running in an * atomic region then we must not take the fault.. */ if (in_atomic() || !mm) - goto no_context; + goto bad_area_nosemaphore; down_read(&mm->mmap_sem); @@ -198,8 +348,16 @@ good_area: bad_area: up_read(&mm->mmap_sem); +bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { + /* + * Valid to do another page fault here because this one came + * from user space. + */ + if (is_prefetch(regs, address)) + return; + tsk->thread.cr2 = address; tsk->thread.error_code = error_code; tsk->thread.trap_no = 14; @@ -232,6 +390,14 @@ no_context: if (fixup_exception(regs)) return; + /* + * Valid to do another page fault here, because if this fault + * had been triggered by is_prefetch fixup_exception would have + * handled it. + */ + if (is_prefetch(regs, address)) + return; + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. @@ -247,6 +413,13 @@ no_context: printk(" printing eip:\n"); printk("%08lx\n", regs->eip); asm("movl %%cr3,%0":"=r" (page)); +#ifdef CONFIG_HIGHPMD /* Oh boy. Error reporting is going to blow major goats. */ + printk(KERN_ALERT "%%cr3 = 0x%lx\n", page); + /* Mask off flag bits. It should end up 32B-aligned. */ + page &= ~(PTRS_PER_PGD*sizeof(pgd_t) - 1); + printk(KERN_ALERT "*pdpte = 0x%Lx\n", + pgd_val(((pgd_t *)__va(page))[address >> PGDIR_SHIFT])); +#else /* !CONFIG_HIGHPMD */ page = ((unsigned long *) __va(page))[address >> 22]; printk(KERN_ALERT "*pde = %08lx\n", page); /* @@ -262,7 +435,8 @@ no_context: page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; printk(KERN_ALERT "*pte = %08lx\n", page); } -#endif +#endif /* !CONFIG_HIGHPTE */ +#endif /* CONFIG_HIGHPMD */ die("Oops", regs, error_code); bust_spinlocks(0); do_exit(SIGKILL); @@ -286,10 +460,14 @@ out_of_memory: do_sigbus: up_read(&mm->mmap_sem); - /* - * Send a sigbus, regardless of whether we were in kernel - * or user mode. - */ + /* Kernel mode? Handle exceptions or die */ + if (!(error_code & 4)) + goto no_context; + + /* User space => ok to do another page fault */ + if (is_prefetch(regs, address)) + return; + tsk->thread.cr2 = address; tsk->thread.error_code = error_code; tsk->thread.trap_no = 14; @@ -298,10 +476,6 @@ do_sigbus: info.si_code = BUS_ADRERR; info.si_addr = (void *)address; force_sig_info(SIGBUS, &info, tsk); - - /* Kernel mode? Handle exceptions or die */ - if (!(error_code & 4)) - goto no_context; return; vmalloc_fault: @@ -330,8 +504,8 @@ vmalloc_fault: * and redundant with the set_pmd() on non-PAE. */ - pmd = pmd_offset(pgd, address); - pmd_k = pmd_offset(pgd_k, address); + pmd = pmd_offset_kernel(pgd, address); + pmd_k = pmd_offset_kernel(pgd_k, address); if (!pmd_present(*pmd_k)) goto no_context; set_pmd(pmd, *pmd_k); diff -prauN linux-2.6.0-test7/arch/i386/mm/highmem.c wli-2.6.0-test7-bk5-36/arch/i386/mm/highmem.c --- linux-2.6.0-test7/arch/i386/mm/highmem.c 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/highmem.c 2003-10-14 20:04:59.000000000 -0700 @@ -1,21 +1,5 @@ #include - -void *kmap(struct page *page) -{ - might_sleep(); - if (page < highmem_start_page) - return page_address(page); - return kmap_high(page); -} - -void kunmap(struct page *page) -{ - if (in_interrupt()) - BUG(); - if (page < highmem_start_page) - return; - kunmap_high(page); -} +#include /* * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because @@ -25,40 +9,40 @@ void kunmap(struct page *page) * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ -void *kmap_atomic(struct page *page, enum km_type type) +void *__kmap_atomic(struct page *page, enum km_type type, unsigned long vaddr) { enum fixed_addresses idx; - unsigned long vaddr; + unsigned long offset = KM_TYPE_NR*smp_processor_id(); + pte_t old_pte, pte, *kpte; - inc_preempt_count(); - if (page < highmem_start_page) - return page_address(page); - - idx = type + KM_TYPE_NR*smp_processor_id(); - vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + idx = type + offset; + vaddr -= PAGE_SIZE*offset; + kpte = kmap_pte - idx; + old_pte = *kpte; #ifdef CONFIG_DEBUG_HIGHMEM - if (!pte_none(*(kmap_pte-idx))) - BUG(); + BUG_ON(!pte_none(old_pte)); #endif - set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); - __flush_tlb_one(vaddr); - - return (void*) vaddr; + pte = mk_pte(page, kmap_prot); + if (!pte_same(old_pte, pte)) { + set_pte(kpte, pte); + if (!pte_none(old_pte)) + __flush_tlb_one(vaddr); + } + return (void *)vaddr; } +EXPORT_SYMBOL(__kmap_atomic); -void kunmap_atomic(void *kvaddr, enum km_type type) -{ #ifdef CONFIG_DEBUG_HIGHMEM - unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; - enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); +void __kunmap_atomic(void *kvaddr, enum km_type type, unsigned long vaddr) +{ + unsigned long offset = KM_TYPE_NR*smp_processor_id(); + unsigned long uvaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx; - if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - return; - } + idx = type + offset; + vaddr -= PAGE_SIZE*offset; - if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) - BUG(); + BUG_ON(uvaddr != vaddr); /* * force other mappings to Oops if they'll try to access @@ -66,21 +50,6 @@ void kunmap_atomic(void *kvaddr, enum km */ pte_clear(kmap_pte-idx); __flush_tlb_one(vaddr); -#endif - - dec_preempt_count(); } - -struct page *kmap_atomic_to_page(void *ptr) -{ - unsigned long idx, vaddr = (unsigned long)ptr; - pte_t *pte; - - if (vaddr < FIXADDR_START) - return virt_to_page(ptr); - - idx = virt_to_fix(vaddr); - pte = kmap_pte - (idx - FIX_KMAP_BEGIN); - return pte_page(*pte); -} - +EXPORT_SYMBOL(__kunmap_atomic); +#endif diff -prauN linux-2.6.0-test7/arch/i386/mm/hugetlbpage.c wli-2.6.0-test7-bk5-36/arch/i386/mm/hugetlbpage.c --- linux-2.6.0-test7/arch/i386/mm/hugetlbpage.c 2003-10-08 12:24:45.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/hugetlbpage.c 2003-10-14 03:01:39.000000000 -0700 @@ -87,8 +87,8 @@ static pte_t *huge_pte_alloc(struct mm_s pmd_t *pmd = NULL; pgd = pgd_offset(mm, addr); - pmd = pmd_alloc(mm, pgd, addr); - return (pte_t *) pmd; + pmd = pmd_alloc_map(mm, pgd, addr); + return (pte_t *)pmd; } static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) @@ -97,11 +97,13 @@ static pte_t *huge_pte_offset(struct mm_ pmd_t *pmd = NULL; pgd = pgd_offset(mm, addr); - pmd = pmd_offset(pgd, addr); - return (pte_t *) pmd; + pmd = pmd_offset_map_nested(pgd, addr); + return (pte_t *)pmd; } -static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access) +static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, + struct page *page, pte_t * page_table, + unsigned long addr, int write_access) { pte_t entry; @@ -114,6 +116,7 @@ static void set_huge_pte(struct mm_struc entry = pte_mkyoung(entry); mk_pte_huge(entry); set_pte(page_table, entry); + vm_account_huge_inc(vma, *page_table, addr); } /* @@ -145,6 +148,8 @@ int copy_hugetlb_page_range(struct mm_st ptepage = pte_page(entry); get_page(ptepage); set_pte(dst_pte, entry); + pmd_unmap(dst_pte); + pmd_unmap_nested(src_pte); dst->rss += (HPAGE_SIZE / PAGE_SIZE); addr += HPAGE_SIZE; } @@ -182,6 +187,7 @@ follow_hugetlb_page(struct mm_struct *mm get_page(page); pages[i] = page; + pmd_unmap_nested(pte); } if (vmas) @@ -271,6 +277,7 @@ follow_huge_pmd(struct mm_struct *mm, un page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT); get_page(page); } + pmd_unmap(pmd); return page; } #endif @@ -278,7 +285,7 @@ follow_huge_pmd(struct mm_struct *mm, un void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); + BUG_ON(page_mapping(page)); INIT_LIST_HEAD(&page->list); @@ -314,6 +321,8 @@ void unmap_hugepage_range(struct vm_area page = pte_page(*pte); huge_page_release(page); pte_clear(pte); + vm_account_huge_dec(vma, *pte, address); + pmd_unmap_nested(pte); } mm->rss -= (end - start) >> PAGE_SHIFT; flush_tlb_range(vma, start, end); @@ -348,8 +357,10 @@ int hugetlb_prefault(struct address_spac ret = -ENOMEM; goto out; } - if (!pte_none(*pte)) + if (!pte_none(*pte)) { + pmd_unmap(pte); continue; + } idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); @@ -358,12 +369,14 @@ int hugetlb_prefault(struct address_spac /* charge the fs quota first */ if (hugetlb_get_quota(mapping)) { ret = -ENOMEM; + pmd_unmap(pte); goto out; } page = alloc_hugetlb_page(); if (!page) { hugetlb_put_quota(mapping); ret = -ENOMEM; + pmd_unmap(pte); goto out; } ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); @@ -371,10 +384,12 @@ int hugetlb_prefault(struct address_spac if (ret) { hugetlb_put_quota(mapping); free_huge_page(page); + pmd_unmap(pte); goto out; } } - set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE); + set_huge_pte(mm, vma, page, pte, addr, vma->vm_flags & VM_WRITE); + pmd_unmap(pte); } out: spin_unlock(&mm->page_table_lock); diff -prauN linux-2.6.0-test7/arch/i386/mm/init.c wli-2.6.0-test7-bk5-36/arch/i386/mm/init.c --- linux-2.6.0-test7/arch/i386/mm/init.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/init.c 2003-10-14 02:57:50.000000000 -0700 @@ -57,10 +57,10 @@ static pmd_t * __init one_md_table_init( #ifdef CONFIG_X86_PAE pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - if (pmd_table != pmd_offset(pgd, 0)) + if (pmd_table != pmd_offset_kernel(pgd, 0)) BUG(); #else - pmd_table = pmd_offset(pgd, 0); + pmd_table = pmd_offset_kernel(pgd, 0); #endif return pmd_table; @@ -111,7 +111,7 @@ static void __init page_table_range_init if (pgd_none(*pgd)) one_md_table_init(pgd); - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { if (pmd_none(*pmd)) one_page_table_init(pmd); @@ -195,7 +195,7 @@ EXPORT_SYMBOL(kmap_prot); EXPORT_SYMBOL(kmap_pte); #define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + pte_offset_kernel(pmd_offset_kernel(pgd_offset_k(vaddr), (vaddr)), (vaddr)) void __init kmap_init(void) { @@ -219,7 +219,7 @@ void __init permanent_kmaps_init(pgd_t * page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); pgd = swapper_pg_dir + pgd_index(vaddr); - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); pte = pte_offset_kernel(pmd, vaddr); pkmap_page_table = pte; } @@ -466,7 +466,7 @@ void __init mem_init(void) /* this will put all low memory onto the freelists */ totalram_pages += __free_all_bootmem(); - + tlb_init(); reservedpages = 0; for (tmp = 0; tmp < max_low_pfn; tmp++) /* @@ -514,20 +514,9 @@ void __init mem_init(void) } kmem_cache_t *pgd_cache; -kmem_cache_t *pmd_cache; void __init pgtable_cache_init(void) { - if (PTRS_PER_PMD > 1) { - pmd_cache = kmem_cache_create("pmd", - PTRS_PER_PMD*sizeof(pmd_t), - 0, - SLAB_HWCACHE_ALIGN | SLAB_MUST_HWCACHE_ALIGN, - pmd_ctor, - NULL); - if (!pmd_cache) - panic("pgtable_cache_init(): cannot create pmd cache"); - } pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD*sizeof(pgd_t), 0, diff -prauN linux-2.6.0-test7/arch/i386/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/i386/mm/ioremap.c --- linux-2.6.0-test7/arch/i386/mm/ioremap.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -82,7 +82,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/i386/mm/pageattr.c wli-2.6.0-test7-bk5-36/arch/i386/mm/pageattr.c --- linux-2.6.0-test7/arch/i386/mm/pageattr.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/pageattr.c 2003-10-14 02:53:51.000000000 -0700 @@ -23,7 +23,7 @@ static inline pte_t *lookup_address(unsi pmd_t *pmd; if (pgd_none(*pgd)) return NULL; - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_kernel(pgd, address); if (pmd_none(*pmd)) return NULL; if (pmd_large(*pmd)) @@ -79,7 +79,7 @@ static void set_pmd_pte(pte_t *kpte, uns pgd_t *pgd; pmd_t *pmd; pgd = (pgd_t *)page_address(page) + pgd_index(address); - pmd = pmd_offset(pgd, address); + pmd = pmd_offset_kernel(pgd, address); set_pte_atomic((pte_t *)pmd, pte); } spin_unlock_irqrestore(&pgd_lock, flags); @@ -92,7 +92,7 @@ static void set_pmd_pte(pte_t *kpte, uns static inline void revert_page(struct page *kpte_page, unsigned long address) { pte_t *linear = (pte_t *) - pmd_offset(pgd_offset(&init_mm, address), address); + pmd_offset_kernel(pgd_offset_k(address), address); set_pmd_pte(linear, address, pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); diff -prauN linux-2.6.0-test7/arch/i386/mm/pgtable.c wli-2.6.0-test7-bk5-36/arch/i386/mm/pgtable.c --- linux-2.6.0-test7/arch/i386/mm/pgtable.c 2003-10-08 12:24:53.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/i386/mm/pgtable.c 2003-10-14 03:07:51.000000000 -0700 @@ -70,7 +70,7 @@ static void set_pte_pfn(unsigned long va BUG(); return; } - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); if (pmd_none(*pmd)) { BUG(); return; @@ -110,7 +110,7 @@ void set_pmd_pfn(unsigned long vaddr, un printk ("set_pmd_pfn: pgd_none\n"); return; /* BUG(); */ } - pmd = pmd_offset(pgd, vaddr); + pmd = pmd_offset_kernel(pgd, vaddr); set_pmd(pmd, pfn_pmd(pfn, flags)); /* * It's enough to flush this one mapping. @@ -138,23 +138,76 @@ pte_t *pte_alloc_one_kernel(struct mm_st return pte; } -struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +void tlb_init(void) { - struct page *pte; + int cpu; + for (cpu = 0; cpu < NR_CPUS; ++cpu) { + int zone; + struct mmu_gather *tlb = &per_cpu(mmu_gathers, cpu); + for (zone = 0; zone < MAX_ZONE_ID; ++zone) { + INIT_LIST_HEAD(&tlb->active_list[zone]); + INIT_LIST_HEAD(&tlb->ready_list[zone]); + } + } +} -#ifdef CONFIG_HIGHPTE - pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0); -#else - pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0); -#endif - if (pte) - clear_highpage(pte); - return pte; +static inline struct page *pte_alloc_fresh(int gfp_mask) +{ + struct page *page = alloc_page(gfp_mask); + if (page) { + clear_highpage(page); + if (TestSetPagePTE(page)) + BUG(); + } + return page; } -void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags) +static inline int zone_high(struct zone *zone) { - memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); + if (!zone) + return 1; + else + return zone - zone->zone_pgdat->node_zones >= ZONE_HIGHMEM; +} + +static inline struct page *pte_alloc_ready(int gfp_flags) +{ + struct mmu_gather *tlb = &per_cpu(mmu_gathers, get_cpu()); + unsigned long flags; + struct page *page = NULL; + + smp_local_irq_save(flags); + if (tlb->nr_pte_ready) { + int z; + for (z = MAX_ZONE_ID - 1; z >= 0; --z) { + struct zone *zone = zone_table[z]; + if (!(gfp_flags & __GFP_HIGHMEM) && zone_high(zone)) + continue; + if (!list_empty(&tlb->ready_list[z])) + break; + } + page = list_entry(tlb->ready_list[z].next, struct page, list); + if (TestSetPagePTE(page)) + BUG(); + list_del(&page->list); + tlb->ready_count[z]--; + tlb->nr_pte_ready--; + } + smp_local_irq_restore(flags); + put_cpu(); + return page; +} + +struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *page = pte_alloc_ready(GFP_PTE); + return page ? page : pte_alloc_fresh(GFP_PTE); +} + +static inline struct page *__pmd_alloc_one(void) +{ + struct page *page = pte_alloc_ready(GFP_PMD); + return page ? page : pte_alloc_fresh(GFP_PMD); } /* @@ -212,16 +265,21 @@ pgd_t *pgd_alloc(struct mm_struct *mm) return pgd; for (i = 0; i < USER_PTRS_PER_PGD; ++i) { - pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); + struct page *pmd = __pmd_alloc_one(); if (!pmd) goto out_oom; - set_pgd(&pgd[i], __pgd(1 + __pa((u64)((u32)pmd)))); + set_pgd(&pgd[i], __pgd(1ULL | (u64)page_to_pfn(pmd) << PAGE_SHIFT)); } return pgd; + /* + * This looks unusual. pte_free() is actually a convenient wrapper + * for queueing up preconstructed pmd and/or pte pages. The cases + * fall through to just queueing them in the per-cpu lists. + */ out_oom: for (i--; i >= 0; i--) - kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + pte_free(pgd_page(pgd[i])); kmem_cache_free(pgd_cache, pgd); return NULL; } @@ -233,7 +291,110 @@ void pgd_free(pgd_t *pgd) /* in the PAE case user pgd entries are overwritten before usage */ if (PTRS_PER_PMD > 1) for (i = 0; i < USER_PTRS_PER_PGD; ++i) - kmem_cache_free(pmd_cache, (void *)__va(pgd_val(pgd[i])-1)); + pte_free(pgd_page(pgd[i])); /* in the non-PAE case, clear_page_tables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); } + +static void shrink_cpu_pagetable_cache(void *__gfp_mask) +{ + int cpu, zone, high, gfp_mask = (int)gfp_mask; + unsigned long flags; + struct mmu_gather *tlb; + + high = !!(gfp_mask & __GFP_HIGHMEM); + cpu = get_cpu(); + tlb = &per_cpu(mmu_gathers, cpu); + smp_local_irq_save(flags); + + if (tlb->nr_pte_active || tlb->nr_nonpte) + tlb_flush(tlb); + + if (tlb->nr_pte_active) { + for (zone = 0; zone < MAX_ZONE_ID; ++zone) { + if (!high && zone_high(zone_table[zone])) + continue; + if (!tlb->active_count[zone]) + continue; + + list_splice_init(&tlb->active_list[zone], &tlb->ready_list[zone]); + tlb->ready_count[zone] += tlb->active_count[zone]; + tlb->active_count[zone] = 0; + } + tlb->nr_pte_ready += tlb->nr_pte_active; + tlb->nr_pte_active = 0; + } + + for (zone = 0; zone < MAX_ZONE_ID; ++zone) { + struct page *head; + + if (list_empty(&tlb->ready_list[zone])) + continue; + if (!high && zone_high(zone_table[zone])) + continue; + + head = list_entry(tlb->ready_list[zone].next, struct page, list); + list_del_init(&head->list); + list_splice_init(&tlb->ready_list[zone], &head->list); + head->private = tlb->ready_count[zone]; + tlb->nr_pte_ready -= tlb->ready_count[zone]; + tlb->ready_count[zone] = 0; + free_pages_bulk(zone_table[zone], head, 0); + } + + smp_local_irq_restore(flags); + put_cpu(); +} + +void shrink_pagetable_cache(int gfp_mask) +{ + BUG_ON(irqs_disabled()); + + preempt_disable(); + + /* disables interrupts appropriately internally */ + shrink_cpu_pagetable_cache((void *)gfp_mask); + + smp_call_function(shrink_cpu_pagetable_cache, (void *)gfp_mask, 1, 1); + preempt_enable(); +} + +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma, *prev; + + len = PAGE_ALIGN(len); + addr = PAGE_ALIGN(addr); + + if (len > TASK_SIZE) + return -ENOMEM; + + if (addr) { + struct vm_area_struct *vma; + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && (!vma || addr + len <= vma->vm_start)) + goto out; + } + + if (!mm->mmap) { + addr = TASK_SIZE - len; + goto out; + } + + addr = -ENOMEM; + for (prev = NULL, vma = mm->mmap; vma; prev = vma, vma = vma->vm_next) { + unsigned long lo, hi; + lo = prev ? prev->vm_end : 0; + hi = vma->vm_start; + if (hi - lo >= len && (addr == -ENOMEM || addr < hi - len)) + addr = hi - len; + } + /* we're at the last one; let's try the top */ + if (prev && TASK_SIZE - prev->vm_end >= len) + addr = TASK_SIZE - len; +out: + return addr; +} diff -prauN linux-2.6.0-test7/arch/ia64/Kconfig wli-2.6.0-test7-bk5-36/arch/ia64/Kconfig --- linux-2.6.0-test7/arch/ia64/Kconfig 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -220,24 +220,8 @@ config NUMA Access). This option is for configuring high-end multiprocessor server systems. If in doubt, say N. -choice - prompt "Maximum Memory per NUMA Node" if NUMA && IA64_DIG - depends on NUMA && IA64_DIG - default IA64_NODESIZE_16GB - -config IA64_NODESIZE_16GB - bool "16GB" - -config IA64_NODESIZE_64GB - bool "64GB" - -config IA64_NODESIZE_256GB - bool "256GB" - -endchoice - config DISCONTIGMEM - bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA + bool "Discontiguous memory support" if (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC) && NUMA && VIRTUAL_MEM_MAP default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA help Say Y to support efficient handling of discontiguous physical memory, @@ -250,14 +234,10 @@ config VIRTUAL_MEM_MAP default y if !IA64_HP_SIM help Say Y to compile the kernel with support for a virtual mem map. - This is an alternate method of supporting large holes in the - physical address space on non NUMA machines. Since the DISCONTIGMEM - option is not supported on machines with the ZX1 chipset, this is - the only way of supporting more than 1 Gb of memory on those - machines. This code also only takes effect if a memory hole of - greater than 1 Gb is found during boot, so it is safe to enable - unless you require the DISCONTIGMEM option for your machine. If you - are unsure, say Y. + This code also only takes effect if a memory hole of greater than + 1 Gb is found during boot. You must turn this option on if you + require the DISCONTIGMEM option for your machine. If you are + unsure, say Y. config IA64_MCA bool "Enable IA-64 Machine Check Abort" diff -prauN linux-2.6.0-test7/arch/ia64/Makefile wli-2.6.0-test7-bk5-36/arch/ia64/Makefile --- linux-2.6.0-test7/arch/ia64/Makefile 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -64,7 +64,7 @@ core-$(CONFIG_IA64_SGI_SN2) += arch/ia64 drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ -drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot diff -prauN linux-2.6.0-test7/arch/ia64/ia32/binfmt_elf32.c wli-2.6.0-test7-bk5-36/arch/ia64/ia32/binfmt_elf32.c --- linux-2.6.0-test7/arch/ia64/ia32/binfmt_elf32.c 2003-10-08 12:24:46.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/ia32/binfmt_elf32.c 2003-10-14 02:58:33.000000000 -0700 @@ -203,7 +203,8 @@ ia32_setup_arg_pages (struct linux_binpr struct page *page = bprm->page[i]; if (page) { bprm->page[i] = NULL; - put_dirty_page(current, page, stack_base, PAGE_COPY); + put_dirty_page(current, mpnt, page, + stack_base, PAGE_COPY); } stack_base += PAGE_SIZE; } diff -prauN linux-2.6.0-test7/arch/ia64/ia32/sys_ia32.c wli-2.6.0-test7-bk5-36/arch/ia64/ia32/sys_ia32.c --- linux-2.6.0-test7/arch/ia64/ia32/sys_ia32.c 2003-10-08 12:24:16.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/ia32/sys_ia32.c 2003-10-14 02:49:46.000000000 -0700 @@ -2486,11 +2486,14 @@ static int putstat64 (struct stat64 *ubuf, struct kstat *kbuf) { int err; + u64 hdev; if (clear_user(ubuf, sizeof(*ubuf))) return -EFAULT; - err = __put_user(huge_encode_dev(kbuf->dev), &ubuf->st_dev); + hdev = huge_encode_dev(kbuf->dev); + err = __put_user(hdev, (u32*)&ubuf->st_dev); + err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_dev) + 1); err |= __put_user(kbuf->ino, &ubuf->__st_ino); err |= __put_user(kbuf->ino, &ubuf->st_ino_lo); err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi); @@ -2498,7 +2501,9 @@ putstat64 (struct stat64 *ubuf, struct k err |= __put_user(kbuf->nlink, &ubuf->st_nlink); err |= __put_user(kbuf->uid, &ubuf->st_uid); err |= __put_user(kbuf->gid, &ubuf->st_gid); - err |= __put_user(huge_encode_dev(kbuf->rdev), &ubuf->st_rdev); + hdev = huge_encode_dev(kbuf->rdev); + err = __put_user(hdev, (u32*)&ubuf->st_rdev); + err |= __put_user(hdev >> 32, ((u32*)&ubuf->st_rdev) + 1); err |= __put_user(kbuf->size, &ubuf->st_size_lo); err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi); err |= __put_user(kbuf->atime.tv_sec, &ubuf->st_atime); @@ -2724,8 +2729,8 @@ out_error: struct epoll_event32 { u32 events; - u64 data; -} __attribute__((packed)); + u32 data[2]; +}; asmlinkage long sys32_epoll_ctl(int epfd, int op, int fd, struct epoll_event32 *event) @@ -2740,10 +2745,10 @@ sys32_epoll_ctl(int epfd, int op, int fd return error; __get_user(event64.events, &event->events); - __get_user(data_halfword, (u32*)(&event->data)); + __get_user(data_halfword, &event->data[0]); event64.data = data_halfword; - __get_user(data_halfword, ((u32*)(&event->data) + 1)); - event64.data |= ((u64)data_halfword) << 32; + __get_user(data_halfword, &event->data[1]); + event64.data |= (u64)data_halfword << 32; set_fs(KERNEL_DS); error = sys_epoll_ctl(epfd, op, fd, &event64); @@ -2758,8 +2763,9 @@ sys32_epoll_wait(int epfd, struct epoll_ { struct epoll_event *events64 = NULL; mm_segment_t old_fs = get_fs(); - int error; + int error, numevents, size; int evt_idx; + int do_free_pages = 0; if (maxevents <= 0) { return -EINVAL; @@ -2770,43 +2776,45 @@ sys32_epoll_wait(int epfd, struct epoll_ maxevents * sizeof(struct epoll_event32)))) return error; - /* Allocate the space needed for the intermediate copy */ - events64 = kmalloc(maxevents * sizeof(struct epoll_event), GFP_KERNEL); + /* + * Allocate space for the intermediate copy. If the space needed + * is large enough to cause kmalloc to fail, then try again with + * __get_free_pages. + */ + size = maxevents * sizeof(struct epoll_event); + events64 = kmalloc(size, GFP_KERNEL); if (events64 == NULL) { - return -ENOMEM; - } - - /* Expand the 32-bit structures into the 64-bit structures */ - for (evt_idx = 0; evt_idx < maxevents; evt_idx++) { - u32 data_halfword; - __get_user(events64[evt_idx].events, &events[evt_idx].events); - __get_user(data_halfword, (u32*)(&events[evt_idx].data)); - events64[evt_idx].data = data_halfword; - __get_user(data_halfword, ((u32*)(&events[evt_idx].data) + 1)); - events64[evt_idx].data |= ((u64)data_halfword) << 32; + events64 = (struct epoll_event *) + __get_free_pages(GFP_KERNEL, get_order(size)); + if (events64 == NULL) + return -ENOMEM; + do_free_pages = 1; } /* Do the system call */ set_fs(KERNEL_DS); /* copy_to/from_user should work on kernel mem*/ - error = sys_epoll_wait(epfd, events64, maxevents, timeout); + numevents = sys_epoll_wait(epfd, events64, maxevents, timeout); set_fs(old_fs); /* Don't modify userspace memory if we're returning an error */ - if (!error) { + if (numevents > 0) { /* Translate the 64-bit structures back into the 32-bit structures */ - for (evt_idx = 0; evt_idx < maxevents; evt_idx++) { + for (evt_idx = 0; evt_idx < numevents; evt_idx++) { __put_user(events64[evt_idx].events, &events[evt_idx].events); - __put_user((u32)(events64[evt_idx].data), - (u32*)(&events[evt_idx].data)); + __put_user((u32)events64[evt_idx].data, + &events[evt_idx].data[0]); __put_user((u32)(events64[evt_idx].data >> 32), - ((u32*)(&events[evt_idx].data) + 1)); + &events[evt_idx].data[1]); } } - kfree(events64); - return error; + if (do_free_pages) + free_pages((unsigned long) events64, get_order(size)); + else + kfree(events64); + return numevents; } #ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */ diff -prauN linux-2.6.0-test7/arch/ia64/kernel/acpi.c wli-2.6.0-test7-bk5-36/arch/ia64/kernel/acpi.c --- linux-2.6.0-test7/arch/ia64/kernel/acpi.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/kernel/acpi.c 2003-10-14 02:49:46.000000000 -0700 @@ -380,7 +380,7 @@ acpi_numa_processor_affinity_init (struc void __init acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma) { - unsigned long paddr, size, hole_size, min_hole_size; + unsigned long paddr, size; u8 pxm; struct node_memblk_s *p, *q, *pend; @@ -402,34 +402,6 @@ acpi_numa_memory_affinity_init (struct a if (!ma->flags.enabled) return; - /* - * When the chunk is not the first one in the node, check distance - * from the other chunks. When the hole is too huge ignore the chunk. - * This restriction should be removed when multiple chunks per node - * is supported. - */ - pend = &node_memblk[num_memblks]; - min_hole_size = 0; - for (p = &node_memblk[0]; p < pend; p++) { - if (p->nid != pxm) - continue; - if (p->start_paddr < paddr) - hole_size = paddr - (p->start_paddr + p->size); - else - hole_size = p->start_paddr - (paddr + size); - - if (!min_hole_size || hole_size < min_hole_size) - min_hole_size = hole_size; - } - - if (min_hole_size) { - if (min_hole_size > size) { - printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n", - size/(1024*1024), paddr); - return; - } - } - /* record this node in proximity bitmap */ pxm_bit_set(pxm); @@ -454,6 +426,12 @@ acpi_numa_arch_fixup (void) { int i, j, node_from, node_to; + /* If there's no SRAT, fix the phys_id */ + if (srat_num_cpus == 0) { + node_cpuid[0].phys_id = hard_smp_processor_id(); + return; + } + /* calculate total number of nodes in system from PXM bitmap */ numnodes = 0; /* init total nodes in system */ @@ -614,6 +592,12 @@ acpi_boot_init (void) smp_build_cpu_map(); # ifdef CONFIG_NUMA + if (srat_num_cpus == 0) { + int cpu, i = 1; + for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++) + if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) + node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; + } build_cpu_to_node_map(); # endif #endif diff -prauN linux-2.6.0-test7/arch/ia64/kernel/mca_asm.S wli-2.6.0-test7-bk5-36/arch/ia64/kernel/mca_asm.S --- linux-2.6.0-test7/arch/ia64/kernel/mca_asm.S 2003-10-08 12:24:43.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/kernel/mca_asm.S 2003-10-14 02:49:46.000000000 -0700 @@ -265,15 +265,15 @@ cSaveCRs: add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r4 - mov r3=cr0 // cr.dcr - mov r5=cr1 // cr.itm - mov r7=cr2;; // cr.iva + mov r3=cr.dcr + mov r5=cr.itm + mov r7=cr.iva;; st8 [r2]=r3,8*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; // 48 byte rements - mov r3=cr8;; // cr.pta + mov r3=cr.pta;; st8 [r2]=r3,8*8;; // 64 byte rements // if PSR.ic=0, reading interruption registers causes an illegal operation fault @@ -286,23 +286,23 @@ begin_skip_intr_regs: add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr16 // cr.ipsr - mov r5=cr17 // cr.isr - mov r7=r0;; // cr.ida => cr18 (reserved) + mov r3=cr.ipsr + mov r5=cr.isr + mov r7=r0;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr19 // cr.iip - mov r5=cr20 // cr.idtr - mov r7=cr21;; // cr.iitr + mov r3=cr.iip + mov r5=cr.ifa + mov r7=cr.itir;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=cr22 // cr.iipa - mov r5=cr23 // cr.ifs - mov r7=cr24;; // cr.iim + mov r3=cr.iipa + mov r5=cr.ifs + mov r7=cr.iim;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; @@ -311,104 +311,101 @@ begin_skip_intr_regs: st8 [r2]=r3,160;; // 160 byte rement SkipIntrRegs: - st8 [r2]=r0,168 // another 168 byte . + st8 [r2]=r0,152;; // another 152 byte . - mov r3=cr66;; // cr.lid - st8 [r2]=r3,40 // 40 byte rement + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2 // duplicate r2 in r6 - mov r3=cr71;; // cr.ivr - st8 [r2]=r3,8 - - mov r3=cr72;; // cr.tpr - st8 [r2]=r3,24 // 24 byte increment - - mov r3=r0;; // cr.eoi => cr75 - st8 [r2]=r3,168 // 168 byte inc. - - mov r3=r0;; // cr.irr0 => cr96 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr1 => cr98 - st8 [r2]=r3,16 // 16 byte inc. - - mov r3=r0;; // cr.irr2 => cr100 - st8 [r2]=r3,16 // 16 byte inc - - mov r3=r0;; // cr.irr3 => cr100 - st8 [r2]=r3,16 // 16b inc. - - mov r3=r0;; // cr.itv => cr114 - st8 [r2]=r3,16 // 16 byte inc. + mov r3=cr.lid +// mov r5=cr.ivr // cr.ivr, don't read it + mov r7=cr.tpr;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.pmv => cr116 - st8 [r2]=r3,8 + mov r3=r0 // cr.eoi => cr67 + mov r5=r0 // cr.irr0 => cr68 + mov r7=r0;; // cr.irr1 => cr69 + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr0 => cr117 - st8 [r2]=r3,8 + mov r3=r0 // cr.irr2 => cr70 + mov r5=r0 // cr.irr3 => cr71 + mov r7=cr.itv;; + st8 [r2]=r3,3*8 + st8 [r4]=r5,3*8 + st8 [r6]=r7,3*8;; - mov r3=r0;; // cr.lrr1 => cr118 - st8 [r2]=r3,8 + mov r3=cr.pmv + mov r5=cr.cmcv;; + st8 [r2]=r3,7*8 + st8 [r4]=r5,7*8;; + + mov r3=r0 // cr.lrr0 => cr80 + mov r5=r0;; // cr.lrr1 => cr81 + st8 [r2]=r3,23*8 + st8 [r4]=r5,23*8;; - mov r3=r0;; // cr.cmcv => cr119 - st8 [r2]=r3,8*10;; + adds r2=25*8,r2;; cSaveARs: // save ARs add r4=8,r2 // duplicate r2 in r4 add r6=2*8,r2 // duplicate r2 in r6 - mov r3=ar0 // ar.kro - mov r5=ar1 // ar.kr1 - mov r7=ar2;; // ar.kr2 + mov r3=ar.k0 + mov r5=ar.k1 + mov r7=ar.k2;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar3 // ar.kr3 - mov r5=ar4 // ar.kr4 - mov r7=ar5;; // ar.kr5 + mov r3=ar.k3 + mov r5=ar.k4 + mov r7=ar.k5;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar6 // ar.kr6 - mov r5=ar7 // ar.kr7 + mov r3=ar.k6 + mov r5=ar.k7 mov r7=r0;; // ar.kr8 st8 [r2]=r3,10*8 st8 [r4]=r5,10*8 st8 [r6]=r7,10*8;; // rement by 72 bytes - mov r3=ar16 // ar.rsc - mov ar16=r0 // put RSE in enforced lazy mode - mov r5=ar17 // ar.bsp + mov r3=ar.rsc + mov ar.rsc=r0 // put RSE in enforced lazy mode + mov r5=ar.bsp ;; - mov r7=ar18;; // ar.bspstore + mov r7=ar.bspstore;; st8 [r2]=r3,3*8 st8 [r4]=r5,3*8 st8 [r6]=r7,3*8;; - mov r3=ar19;; // ar.rnat + mov r3=ar.rnat;; st8 [r2]=r3,8*13 // increment by 13x8 bytes - mov r3=ar32;; // ar.ccv + mov r3=ar.ccv;; st8 [r2]=r3,8*4 - mov r3=ar36;; // ar.unat + mov r3=ar.unat;; st8 [r2]=r3,8*4 - mov r3=ar40;; // ar.fpsr + mov r3=ar.fpsr;; st8 [r2]=r3,8*4 - mov r3=ar44;; // ar.itc + mov r3=ar.itc;; st8 [r2]=r3,160 // 160 - mov r3=ar64;; // ar.pfs + mov r3=ar.pfs;; st8 [r2]=r3,8 - mov r3=ar65;; // ar.lc + mov r3=ar.lc;; st8 [r2]=r3,8 - mov r3=ar66;; // ar.ec + mov r3=ar.ec;; st8 [r2]=r3 add r2=8*62,r2 //padding @@ -417,7 +414,8 @@ cSaveARs: movl r4=0x00;; cStRR: - mov r3=rr[r4];; + dep.z r5=r4,61,3;; + mov r3=rr[r5];; st8 [r2]=r3,8 add r4=1,r4 br.cloop.sptk.few cStRR @@ -501,12 +499,12 @@ restore_CRs: ld8 r3=[r2],8*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; // 48 byte increments - mov cr0=r3 // cr.dcr - mov cr1=r5 // cr.itm - mov cr2=r7;; // cr.iva + mov cr.dcr=r3 + mov cr.itm=r5 + mov cr.iva=r7;; ld8 r3=[r2],8*8;; // 64 byte increments -// mov cr8=r3 // cr.pta +// mov cr.pta=r3 // if PSR.ic=1, reading interruption registers causes an illegal operation fault @@ -523,64 +521,66 @@ begin_rskip_intr_regs: ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr16=r3 // cr.ipsr - mov cr17=r5 // cr.isr is read only -// mov cr18=r7;; // cr.ida (reserved - don't restore) + mov cr.ipsr=r3 +// mov cr.isr=r5 // cr.isr is read only ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr19=r3 // cr.iip - mov cr20=r5 // cr.idtr - mov cr21=r7;; // cr.iitr + mov cr.iip=r3 + mov cr.ifa=r5 + mov cr.itir=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov cr22=r3 // cr.iipa - mov cr23=r5 // cr.ifs - mov cr24=r7 // cr.iim + mov cr.iipa=r3 + mov cr.ifs=r5 + mov cr.iim=r7 ld8 r3=[r2],160;; // 160 byte increment - mov cr25=r3 // cr.iha + mov cr.iha=r3 rSkipIntrRegs: - ld8 r3=[r2],168;; // another 168 byte inc. - - ld8 r3=[r2],40;; // 40 byte increment - mov cr66=r3 // cr.lid - - ld8 r3=[r2],8;; -// mov cr71=r3 // cr.ivr is read only - ld8 r3=[r2],24;; // 24 byte increment - mov cr72=r3 // cr.tpr - - ld8 r3=[r2],168;; // 168 byte inc. -// mov cr75=r3 // cr.eoi + ld8 r3=[r2],152;; // another 152 byte inc. - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr96=r3 // cr.irr0 is read only + add r4=8,r2 // duplicate r2 in r4 + add r6=2*8,r2;; // duplicate r2 in r6 - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr98=r3 // cr.irr1 is read only + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; + mov cr.lid=r3 +// mov cr.ivr=r5 // cr.ivr is read only + mov cr.tpr=r7;; + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.eoi=r3 +// mov cr.irr0=r5 // cr.irr0 is read only +// mov cr.irr1=r7;; // cr.irr1 is read only + + ld8 r3=[r2],8*3 + ld8 r5=[r4],8*3 + ld8 r7=[r6],8*3;; +// mov cr.irr2=r3 // cr.irr2 is read only +// mov cr.irr3=r5 // cr.irr3 is read only + mov cr.itv=r7;; + + ld8 r3=[r2],8*7 + ld8 r5=[r4],8*7;; + mov cr.pmv=r3 + mov cr.cmcv=r5;; + + ld8 r3=[r2],8*23 + ld8 r5=[r4],8*23;; + adds r2=8*23,r2 + adds r4=8*23,r4;; +// mov cr.lrr0=r3 +// mov cr.lrr1=r5 - ld8 r3=[r2],16;; // 16 byte inc -// mov cr100=r3 // cr.irr2 is read only - - ld8 r3=[r2],16;; // 16b inc. -// mov cr102=r3 // cr.irr3 is read only - - ld8 r3=[r2],16;; // 16 byte inc. -// mov cr114=r3 // cr.itv - - ld8 r3=[r2],8;; -// mov cr116=r3 // cr.pmv - ld8 r3=[r2],8;; -// mov cr117=r3 // cr.lrr0 - ld8 r3=[r2],8;; -// mov cr118=r3 // cr.lrr1 - ld8 r3=[r2],8*10;; -// mov cr119=r3 // cr.cmcv + adds r2=8*2,r2;; restore_ARs: add r4=8,r2 // duplicate r2 in r4 @@ -589,67 +589,67 @@ restore_ARs: ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar0=r3 // ar.kro - mov ar1=r5 // ar.kr1 - mov ar2=r7;; // ar.kr2 + mov ar.k0=r3 + mov ar.k1=r5 + mov ar.k2=r7;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; - mov ar3=r3 // ar.kr3 - mov ar4=r5 // ar.kr4 - mov ar5=r7;; // ar.kr5 + mov ar.k3=r3 + mov ar.k4=r5 + mov ar.k5=r7;; ld8 r3=[r2],10*8 ld8 r5=[r4],10*8 ld8 r7=[r6],10*8;; - mov ar6=r3 // ar.kr6 - mov ar7=r5 // ar.kr7 -// mov ar8=r6 // ar.kr8 + mov ar.k6=r3 + mov ar.k7=r5 ;; ld8 r3=[r2],3*8 ld8 r5=[r4],3*8 ld8 r7=[r6],3*8;; -// mov ar16=r3 // ar.rsc -// mov ar17=r5 // ar.bsp is read only - mov ar16=r0 // make sure that RSE is in enforced lazy mode +// mov ar.rsc=r3 +// mov ar.bsp=r5 // ar.bsp is read only + mov ar.rsc=r0 // make sure that RSE is in enforced lazy mode ;; - mov ar18=r7;; // ar.bspstore + mov ar.bspstore=r7;; ld8 r9=[r2],8*13;; - mov ar19=r9 // ar.rnat + mov ar.rnat=r9 - mov ar16=r3 // ar.rsc + mov ar.rsc=r3 ld8 r3=[r2],8*4;; - mov ar32=r3 // ar.ccv + mov ar.ccv=r3 ld8 r3=[r2],8*4;; - mov ar36=r3 // ar.unat + mov ar.unat=r3 ld8 r3=[r2],8*4;; - mov ar40=r3 // ar.fpsr + mov ar.fpsr=r3 ld8 r3=[r2],160;; // 160 -// mov ar44=r3 // ar.itc +// mov ar.itc=r3 ld8 r3=[r2],8;; - mov ar64=r3 // ar.pfs + mov ar.pfs=r3 ld8 r3=[r2],8;; - mov ar65=r3 // ar.lc + mov ar.lc=r3 ld8 r3=[r2];; - mov ar66=r3 // ar.ec + mov ar.ec=r3 add r2=8*62,r2;; // padding restore_RRs: mov r5=ar.lc mov ar.lc=0x08-1 - movl r4=0x00 + movl r4=0x00;; cStRRr: + dep.z r7=r4,61,3 ld8 r3=[r2],8;; -// mov rr[r4]=r3 // what are its access previledges? + mov rr[r7]=r3 // what are its access previledges? add r4=1,r4 br.cloop.sptk.few cStRRr ;; diff -prauN linux-2.6.0-test7/arch/ia64/kernel/setup.c wli-2.6.0-test7-bk5-36/arch/ia64/kernel/setup.c --- linux-2.6.0-test7/arch/ia64/kernel/setup.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/kernel/setup.c 2003-10-14 02:49:46.000000000 -0700 @@ -101,7 +101,7 @@ int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg) { unsigned long range_start, range_end, prev_start; - void (*func)(unsigned long, unsigned long); + void (*func)(unsigned long, unsigned long, int); int i; #if IGNORE_PFN0 @@ -122,11 +122,7 @@ filter_rsvd_memory (unsigned long start, range_end = min(end, rsvd_region[i].start); if (range_start < range_end) -#ifdef CONFIG_DISCONTIGMEM - call_pernode_memory(__pa(range_start), __pa(range_end), func); -#else - (*func)(__pa(range_start), range_end - range_start); -#endif + call_pernode_memory(__pa(range_start), range_end - range_start, func); /* nothing more available in this segment */ if (range_end == end) return 0; @@ -239,7 +235,6 @@ setup_arch (char **cmdline_p) strlcpy(saved_command_line, *cmdline_p, sizeof(saved_command_line)); efi_init(); - find_memory(); #ifdef CONFIG_ACPI_BOOT /* Initialize the ACPI boot-time table parser */ @@ -253,6 +248,8 @@ setup_arch (char **cmdline_p) # endif #endif /* CONFIG_APCI_BOOT */ + find_memory(); + /* process SAL system table: */ ia64_sal_init(efi.sal_systab); @@ -544,28 +541,7 @@ cpu_init (void) struct cpuinfo_ia64 *cpu_info; void *cpu_data; -#ifdef CONFIG_SMP - int cpu; - - /* - * get_free_pages() cannot be used before cpu_init() done. BSP allocates - * "NR_CPUS" pages for all CPUs to avoid that AP calls get_zeroed_page(). - */ - if (smp_processor_id() == 0) { - cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, PERCPU_PAGE_SIZE, - __pa(MAX_DMA_ADDRESS)); - for (cpu = 0; cpu < NR_CPUS; cpu++) { - memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); - __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start; - cpu_data += PERCPU_PAGE_SIZE; - - per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; - } - } - cpu_data = __per_cpu_start + __per_cpu_offset[smp_processor_id()]; -#else /* !CONFIG_SMP */ - cpu_data = __phys_per_cpu_start; -#endif /* !CONFIG_SMP */ + cpu_data = per_cpu_init(); get_max_cacheline_size(); @@ -576,9 +552,6 @@ cpu_init (void) * accessing cpu_data() through the canonical per-CPU address. */ cpu_info = cpu_data + ((char *) &__ia64_per_cpu_var(cpu_info) - __per_cpu_start); -#ifdef CONFIG_NUMA - cpu_info->node_data = get_node_data_ptr(); -#endif identify_cpu(cpu_info); #ifdef CONFIG_MCKINLEY diff -prauN linux-2.6.0-test7/arch/ia64/kernel/unaligned.c wli-2.6.0-test7-bk5-36/arch/ia64/kernel/unaligned.c --- linux-2.6.0-test7/arch/ia64/kernel/unaligned.c 2003-10-08 12:24:44.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/kernel/unaligned.c 2003-10-14 02:49:46.000000000 -0700 @@ -1347,7 +1347,7 @@ ia64_handle_unaligned (unsigned long ifa * be holding locks... */ if (user_mode(regs)) - tty_write_message(process_tty(current), buf); + tty_write_message(current->tty, buf); buf[len-1] = '\0'; /* drop '\r' */ printk(KERN_WARNING "%s", buf); /* watch for command names containing %s */ } diff -prauN linux-2.6.0-test7/arch/ia64/mm/contig.c wli-2.6.0-test7-bk5-36/arch/ia64/mm/contig.c --- linux-2.6.0-test7/arch/ia64/mm/contig.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/mm/contig.c 2003-10-14 02:49:46.000000000 -0700 @@ -25,6 +25,10 @@ #include #include +#ifdef CONFIG_VIRTUAL_MEM_MAP +static unsigned long num_dma_physpages; +#endif + /** * show_mem - display a memory statistics summary * @@ -161,3 +165,133 @@ find_memory (void) find_initrd(); } + +#ifdef CONFIG_SMP +/** + * per_cpu_init - setup per-cpu variables + * + * Allocate and setup per-cpu data areas. + */ +void * +per_cpu_init (void) +{ + void *cpu_data; + int cpu; + + /* + * get_free_pages() cannot be used before cpu_init() done. BSP + * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls + * get_zeroed_page(). + */ + if (smp_processor_id() == 0) { + cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, + PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); + for (cpu = 0; cpu < NR_CPUS; cpu++) { + memcpy(cpu_data, __phys_per_cpu_start, __per_cpu_end - __per_cpu_start); + __per_cpu_offset[cpu] = (char *) cpu_data - __per_cpu_start; + cpu_data += PERCPU_PAGE_SIZE; + per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu]; + } + } + return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; +} +#endif /* CONFIG_SMP */ + +static int +count_pages (u64 start, u64 end, void *arg) +{ + unsigned long *count = arg; + + *count += (end - start) >> PAGE_SHIFT; + return 0; +} + +#ifdef CONFIG_VIRTUAL_MEM_MAP +static int +count_dma_pages (u64 start, u64 end, void *arg) +{ + unsigned long *count = arg; + + if (end <= MAX_DMA_ADDRESS) + *count += (end - start) >> PAGE_SHIFT; + return 0; +} +#endif + +/* + * Set up the page tables. + */ + +void +paging_init (void) +{ + unsigned long max_dma; + unsigned long zones_size[MAX_NR_ZONES]; +#ifdef CONFIG_VIRTUAL_MEM_MAP + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long max_gap; +#endif + + /* initialize mem_map[] */ + + memset(zones_size, 0, sizeof(zones_size)); + + num_physpages = 0; + efi_memmap_walk(count_pages, &num_physpages); + + max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; + +#ifdef CONFIG_VIRTUAL_MEM_MAP + memset(zholes_size, 0, sizeof(zholes_size)); + + num_dma_physpages = 0; + efi_memmap_walk(count_dma_pages, &num_dma_physpages); + + if (max_low_pfn < max_dma) { + zones_size[ZONE_DMA] = max_low_pfn; + zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages; + } else { + zones_size[ZONE_DMA] = max_dma; + zholes_size[ZONE_DMA] = max_dma - num_dma_physpages; + if (num_physpages > num_dma_physpages) { + zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; + zholes_size[ZONE_NORMAL] = + ((max_low_pfn - max_dma) - + (num_physpages - num_dma_physpages)); + } + } + + max_gap = 0; + efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); + if (max_gap < LARGE_GAP) { + vmem_map = (struct page *) 0; + free_area_init_node(0, &contig_page_data, NULL, zones_size, 0, + zholes_size); + mem_map = contig_page_data.node_mem_map; + } else { + unsigned long map_size; + + /* allocate virtual_mem_map */ + + map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmalloc_end -= map_size; + vmem_map = (struct page *) vmalloc_end; + efi_memmap_walk(create_mem_map_page_table, 0); + + free_area_init_node(0, &contig_page_data, vmem_map, zones_size, + 0, zholes_size); + + mem_map = contig_page_data.node_mem_map; + printk("Virtual mem_map starts at 0x%p\n", mem_map); + } +#else /* !CONFIG_VIRTUAL_MEM_MAP */ + if (max_low_pfn < max_dma) + zones_size[ZONE_DMA] = max_low_pfn; + else { + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; + } + free_area_init(zones_size); +#endif /* !CONFIG_VIRTUAL_MEM_MAP */ + zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); +} diff -prauN linux-2.6.0-test7/arch/ia64/mm/discontig.c wli-2.6.0-test7-bk5-36/arch/ia64/mm/discontig.c --- linux-2.6.0-test7/arch/ia64/mm/discontig.c 2003-10-08 12:24:42.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/mm/discontig.c 2003-10-14 02:49:46.000000000 -0700 @@ -17,72 +17,57 @@ #include #include #include +#include #include - - -/* - * Round an address upward to the next multiple of GRANULE size. - */ -#define GRANULEROUNDUP(n) (((n)+IA64_GRANULE_SIZE-1) & ~(IA64_GRANULE_SIZE-1)) - -static struct ia64_node_data *node_data[MAX_NUMNODES]; -static long boot_pg_data[8*MAX_NUMNODES+sizeof(pg_data_t)] __initdata; -static pg_data_t *pg_data_ptr[MAX_NUMNODES] __initdata; -static bootmem_data_t bdata[MAX_NUMNODES][NR_BANKS_PER_NODE+1] __initdata; -/* - * Return the compact node number of this cpu. Used prior to - * setting up the cpu_data area. - * Note - not fast, intended for boot use only!! - */ -int -boot_get_local_nodeid(void) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) - if (node_cpuid[i].phys_id == hard_smp_processor_id()) - return node_cpuid[i].nid; - - /* node info missing, so nid should be 0.. */ - return 0; -} +#include +#include /* - * Return a pointer to the pg_data structure for a node. - * This function is used ONLY in early boot before the cpu_data - * structure is available. + * Track per-node information needed to setup the boot memory allocator, the + * per-node areas, and the real VM. */ -pg_data_t* __init -boot_get_pg_data_ptr(long node) -{ - return pg_data_ptr[node]; -} - - -/* - * Return a pointer to the node data for the current node. - * (boottime initialization only) +struct early_node_data { + struct ia64_node_data *node_data; + pg_data_t *pgdat; + unsigned long pernode_addr; + unsigned long pernode_size; + struct bootmem_data bootmem_data; + unsigned long num_physpages; + unsigned long num_dma_physpages; + unsigned long min_pfn; + unsigned long max_pfn; +}; + +static struct early_node_data mem_data[NR_NODES] __initdata; + +/* + * To prevent cache aliasing effects, align per-node structures so that they + * start at addresses that are strided by node number. + */ +#define NODEDATA_ALIGN(addr, node) \ + ((((addr) + 1024*1024-1) & ~(1024*1024-1)) + (node)*PERCPU_PAGE_SIZE) + +/** + * build_node_maps - callback to setup bootmem structs for each node + * @start: physical start of range + * @len: length of range + * @node: node where this range resides + * + * We allocate a struct bootmem_data for each piece of memory that we wish to + * treat as a virtually contiguous block (i.e. each node). Each such block + * must start on an %IA64_GRANULE_SIZE boundary, so we round the address down + * if necessary. Any non-existent pages will simply be part of the virtual + * memmap. We also update min_low_pfn and max_low_pfn here as we receive + * memory ranges from the caller. */ -struct ia64_node_data * -get_node_data_ptr(void) +static int __init build_node_maps(unsigned long start, unsigned long len, + int node) { - return node_data[boot_get_local_nodeid()]; -} + unsigned long cstart, epfn, end = start + len; + struct bootmem_data *bdp = &mem_data[node].bootmem_data; -/* - * We allocate one of the bootmem_data_t structs for each piece of memory - * that we wish to treat as a contiguous block. Each such block must start - * on a BANKSIZE boundary. Multiple banks per node is not supported. - */ -static int __init -build_maps(unsigned long pstart, unsigned long length, int node) -{ - bootmem_data_t *bdp; - unsigned long cstart, epfn; - - bdp = pg_data_ptr[node]->bdata; - epfn = GRANULEROUNDUP(pstart + length) >> PAGE_SHIFT; - cstart = pstart & ~(BANKSIZE - 1); + epfn = GRANULEROUNDUP(end) >> PAGE_SHIFT; + cstart = GRANULEROUNDDOWN(start); if (!bdp->node_low_pfn) { bdp->node_boot_start = cstart; @@ -98,34 +83,143 @@ build_maps(unsigned long pstart, unsigne return 0; } -/* - * Find space on each node for the bootmem map. +/** + * early_nr_cpus_node - return number of cpus on a given node + * @node: node to check * - * Called by efi_memmap_walk to find boot memory on each node. Note that - * only blocks that are free are passed to this routine (currently filtered by - * free_available_memory). + * Count the number of cpus on @node. We can't use nr_cpus_node() yet because + * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been + * called yet. */ -static int __init -find_bootmap_space(unsigned long pstart, unsigned long length, int node) +static int early_nr_cpus_node(int node) { - unsigned long mapsize, pages, epfn; - bootmem_data_t *bdp; + int cpu, n = 0; - epfn = (pstart + length) >> PAGE_SHIFT; - bdp = &pg_data_ptr[node]->bdata[0]; + for (cpu = 0; cpu < NR_CPUS; cpu++) + if (node == node_cpuid[cpu].nid) + n++; + + return n; +} - if (pstart < bdp->node_boot_start || epfn > bdp->node_low_pfn) +/** + * find_pernode_space - allocate memory for memory map and per-node structures + * @start: physical start of range + * @len: length of range + * @node: node where this range resides + * + * This routine reserves space for the per-cpu data struct, the list of + * pg_data_ts and the per-node data struct. Each node will have something like + * the following in the first chunk of addr. space large enough to hold it. + * + * ________________________ + * | | + * |~~~~~~~~~~~~~~~~~~~~~~~~| <-- NODEDATA_ALIGN(start, node) for the first + * | PERCPU_PAGE_SIZE * | start and length big enough + * | NR_CPUS | + * |------------------------| + * | local pg_data_t * | + * |------------------------| + * | local ia64_node_data | + * |------------------------| + * | ??? | + * |________________________| + * + * Once this space has been set aside, the bootmem maps are initialized. We + * could probably move the allocation of the per-cpu and ia64_node_data space + * outside of this function and use alloc_bootmem_node(), but doing it here + * is straightforward and we get the alignments we want so... + */ +static int __init find_pernode_space(unsigned long start, unsigned long len, + int node) +{ + unsigned long epfn, cpu, cpus; + unsigned long pernodesize = 0, pernode; + void *cpu_data; + struct bootmem_data *bdp = &mem_data[node].bootmem_data; + + epfn = (start + len) >> PAGE_SHIFT; + + /* + * Make sure this memory falls within this node's usable memory + * since we may have thrown some away in build_maps(). + */ + if (start < bdp->node_boot_start || + epfn > bdp->node_low_pfn) return 0; - if (!bdp->node_bootmem_map) { - pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT); + /* Don't setup this node's local space twice... */ + if (!mem_data[node].pernode_addr) { + /* + * Calculate total size needed, incl. what's necessary + * for good alignment and alias prevention. + */ + cpus = early_nr_cpus_node(node); + pernodesize += PERCPU_PAGE_SIZE * cpus; + pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t)); + pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + pernodesize = PAGE_ALIGN(pernodesize); + pernode = NODEDATA_ALIGN(start, node); + + /* Is this range big enough for what we want to store here? */ + if (start + len > (pernode + pernodesize)) { + mem_data[node].pernode_addr = pernode; + mem_data[node].pernode_size = pernodesize; + memset(__va(pernode), 0, pernodesize); + + cpu_data = (void *)pernode; + pernode += PERCPU_PAGE_SIZE * cpus; + + mem_data[node].pgdat = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + mem_data[node].node_data = __va(pernode); + pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); + + mem_data[node].pgdat->bdata = bdp; + pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); + + /* + * Copy the static per-cpu data into the region we + * just set aside and then setup __per_cpu_offset + * for each CPU on this node. + */ + for (cpu = 0; cpu < NR_CPUS; cpu++) { + if (node == node_cpuid[cpu].nid) { + memcpy(cpu_data, __phys_per_cpu_start, + __per_cpu_end-__per_cpu_start); + __per_cpu_offset[cpu] = + (char*)__va(cpu_data) - + __per_cpu_start; + cpu_data += PERCPU_PAGE_SIZE; + } + } + } + } + + pernode = mem_data[node].pernode_addr; + pernodesize = mem_data[node].pernode_size; + if (pernode && !bdp->node_bootmem_map) { + unsigned long pages, mapsize, map = 0; + + pages = bdp->node_low_pfn - + (bdp->node_boot_start >> PAGE_SHIFT); mapsize = bootmem_bootmap_pages(pages) << PAGE_SHIFT; - if (length > mapsize) { - init_bootmem_node( - BOOT_NODE_DATA(node), - pstart>>PAGE_SHIFT, - bdp->node_boot_start>>PAGE_SHIFT, - bdp->node_low_pfn); + + /* + * The map will either contain the pernode area or begin + * after it. + */ + if (pernode - start > mapsize) + map = start; + else if (start + len - pernode - pernodesize > mapsize) + map = pernode + pernodesize; + + if (map) { + init_bootmem_node(mem_data[node].pgdat, + map>>PAGE_SHIFT, + bdp->node_boot_start>>PAGE_SHIFT, + bdp->node_low_pfn); } } @@ -133,85 +227,93 @@ find_bootmap_space(unsigned long pstart, return 0; } - -/* - * Free available memory to the bootmem allocator. - * - * Note that only blocks that are free are passed to this routine (currently - * filtered by free_available_memory). +/** + * free_node_bootmem - free bootmem allocator memory for use + * @start: physical start of range + * @len: length of range + * @node: node where this range resides * + * Simply calls the bootmem allocator to free the specified ranged from + * the given pg_data_t's bdata struct. After this function has been called + * for all the entries in the EFI memory map, the bootmem allocator will + * be ready to service allocation requests. */ -static int __init -discontig_free_bootmem_node(unsigned long pstart, unsigned long length, int node) +static int __init free_node_bootmem(unsigned long start, unsigned long len, + int node) { - free_bootmem_node(BOOT_NODE_DATA(node), pstart, length); + free_bootmem_node(mem_data[node].pgdat, start, len); return 0; } - -/* - * Reserve the space used by the bootmem maps. - */ -static void __init -discontig_reserve_bootmem(void) -{ - int node; - unsigned long mapbase, mapsize, pages; - bootmem_data_t *bdp; +/** + * reserve_pernode_space - reserve memory for per-node space + * + * Reserve the space used by the bootmem maps & per-node space in the boot + * allocator so that when we actually create the real mem maps we don't + * use their memory. + */ +static void __init reserve_pernode_space(void) +{ + unsigned long base, size, pages; + struct bootmem_data *bdp; + int node; for (node = 0; node < numnodes; node++) { - bdp = BOOT_NODE_DATA(node)->bdata; + pg_data_t *pdp = mem_data[node].pgdat; + bdp = pdp->bdata; + + /* First the bootmem_map itself */ pages = bdp->node_low_pfn - (bdp->node_boot_start>>PAGE_SHIFT); - mapsize = bootmem_bootmap_pages(pages) << PAGE_SHIFT; - mapbase = __pa(bdp->node_bootmem_map); - reserve_bootmem_node(BOOT_NODE_DATA(node), mapbase, mapsize); + size = bootmem_bootmap_pages(pages) << PAGE_SHIFT; + base = __pa(bdp->node_bootmem_map); + reserve_bootmem_node(pdp, base, size); + + /* Now the per-node space */ + size = mem_data[node].pernode_size; + base = __pa(mem_data[node].pernode_addr); + reserve_bootmem_node(pdp, base, size); } } -/* - * Allocate per node tables. - * - the pg_data structure is allocated on each node. This minimizes offnode - * memory references - * - the node data is allocated & initialized. Portions of this structure is read-only (after - * boot) and contains node-local pointers to usefuls data structures located on - * other nodes. - * - * We also switch to using the "real" pg_data structures at this point. Earlier in boot, we - * use a different structure. The only use for pg_data prior to the point in boot is to get - * the pointer to the bdata for the node. - */ -static void __init -allocate_pernode_structures(void) -{ - pg_data_t *pgdat=0, *new_pgdat_list=0; - int node, mynode; - - mynode = boot_get_local_nodeid(); - for (node = numnodes - 1; node >= 0 ; node--) { - node_data[node] = alloc_bootmem_node(BOOT_NODE_DATA(node), sizeof (struct ia64_node_data)); - pgdat = __alloc_bootmem_node(BOOT_NODE_DATA(node), sizeof(pg_data_t), SMP_CACHE_BYTES, 0); - pgdat->bdata = &(bdata[node][0]); - pg_data_ptr[node] = pgdat; - pgdat->pgdat_next = new_pgdat_list; - new_pgdat_list = pgdat; - } +/** + * initialize_pernode_data - fixup per-cpu & per-node pointers + * + * Each node's per-node area has a copy of the global pg_data_t list, so + * we copy that to each node here, as well as setting the per-cpu pointer + * to the local node data structure. The active_cpus field of the per-node + * structure gets setup by the platform_cpu_init() function later. + */ +static void __init initialize_pernode_data(void) +{ + int cpu, node; + pg_data_t *pgdat_list[NR_NODES]; - memcpy(node_data[mynode]->pg_data_ptrs, pg_data_ptr, sizeof(pg_data_ptr)); - memcpy(node_data[mynode]->node_data_ptrs, node_data, sizeof(node_data)); + for (node = 0; node < numnodes; node++) + pgdat_list[node] = mem_data[node].pgdat; - pgdat_list = new_pgdat_list; + /* Copy the pg_data_t list to each node and init the node field */ + for (node = 0; node < numnodes; node++) { + memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, + sizeof(pgdat_list)); + } + + /* Set the node_data pointer for each per-cpu struct */ + for (cpu = 0; cpu < NR_CPUS; cpu++) { + node = node_cpuid[cpu].nid; + per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data; + } } -/* - * Called early in boot to setup the boot memory allocator, and to - * allocate the node-local pg_data & node-directory data structures.. +/** + * find_memory - walk the EFI memory map and setup the bootmem allocator + * + * Called early in boot to setup the bootmem allocator, and to + * allocate the per-cpu and per-node structures. */ void __init find_memory(void) { - int node; - reserve_memory(); if (numnodes == 0) { @@ -219,94 +321,48 @@ void __init find_memory(void) numnodes = 1; } - for (node = 0; node < numnodes; node++) { - pg_data_ptr[node] = (pg_data_t*) &boot_pg_data[node]; - pg_data_ptr[node]->bdata = &bdata[node][0]; - } - min_low_pfn = -1; max_low_pfn = 0; - efi_memmap_walk(filter_rsvd_memory, build_maps); - efi_memmap_walk(filter_rsvd_memory, find_bootmap_space); - efi_memmap_walk(filter_rsvd_memory, discontig_free_bootmem_node); - discontig_reserve_bootmem(); - allocate_pernode_structures(); - - find_initrd(); -} - -/* - * Initialize the paging system. - * - determine sizes of each node - * - initialize the paging system for the node - * - build the nodedir for the node. This contains pointers to - * the per-bank mem_map entries. - * - fix the page struct "virtual" pointers. These are bank specific - * values that the paging system doesn't understand. - * - replicate the nodedir structure to other nodes - */ - -void __init -discontig_paging_init(void) -{ - int node, mynode; - unsigned long max_dma, zones_size[MAX_NR_ZONES]; - unsigned long kaddr, ekaddr, bid; - struct page *page; - bootmem_data_t *bdp; - - max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; + /* These actually end up getting called by call_pernode_memory() */ + efi_memmap_walk(filter_rsvd_memory, build_node_maps); + efi_memmap_walk(filter_rsvd_memory, find_pernode_space); + efi_memmap_walk(filter_rsvd_memory, free_node_bootmem); - mynode = boot_get_local_nodeid(); - for (node = 0; node < numnodes; node++) { - long pfn, startpfn; + reserve_pernode_space(); + initialize_pernode_data(); - memset(zones_size, 0, sizeof(zones_size)); + max_pfn = max_low_pfn; - startpfn = -1; - bdp = BOOT_NODE_DATA(node)->bdata; - pfn = bdp->node_boot_start >> PAGE_SHIFT; - if (startpfn == -1) - startpfn = pfn; - if (pfn > max_dma) - zones_size[ZONE_NORMAL] += (bdp->node_low_pfn - pfn); - else if (bdp->node_low_pfn < max_dma) - zones_size[ZONE_DMA] += (bdp->node_low_pfn - pfn); - else { - zones_size[ZONE_DMA] += (max_dma - pfn); - zones_size[ZONE_NORMAL] += (bdp->node_low_pfn - max_dma); - } - - free_area_init_node(node, NODE_DATA(node), NULL, zones_size, startpfn, 0); - - page = NODE_DATA(node)->node_mem_map; + find_initrd(); +} - bdp = BOOT_NODE_DATA(node)->bdata; +/** + * per_cpu_init - setup per-cpu variables + * + * find_pernode_space() does most of this already, we just need to set + * local_per_cpu_offset + */ +void *per_cpu_init(void) +{ + int cpu; - kaddr = (unsigned long)__va(bdp->node_boot_start); - ekaddr = (unsigned long)__va(bdp->node_low_pfn << PAGE_SHIFT); - while (kaddr < ekaddr) { - if (paddr_to_nid(__pa(kaddr)) == node) { - bid = BANK_MEM_MAP_INDEX(kaddr); - node_data[mynode]->node_id_map[bid] = node; - node_data[mynode]->bank_mem_map_base[bid] = page; - } - kaddr += BANKSIZE; - page += BANKSIZE/PAGE_SIZE; + if (smp_processor_id() == 0) { + for (cpu = 0; cpu < NR_CPUS; cpu++) { + per_cpu(local_per_cpu_offset, cpu) = + __per_cpu_offset[cpu]; } } - /* - * Finish setting up the node data for this node, then copy it to the other nodes. - */ - for (node=0; node < numnodes; node++) - if (mynode != node) { - memcpy(node_data[node], node_data[mynode], sizeof(struct ia64_node_data)); - node_data[node]->node = node; - } + return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; } +/** + * show_mem - give short summary of memory stats + * + * Shows a simple page count of reserved and used pages in the system. + * For discontig machines, it does this on a per-pgdat basis. + */ void show_mem(void) { int i, reserved = 0; @@ -335,7 +391,12 @@ void show_mem(void) printk("%d free buffer pages\n", nr_free_buffer_pages()); } -/* +/** + * call_pernode_memory - use SRAT to call callback functions with node info + * @start: physical start of range + * @len: length of range + * @arg: function to call for each range + * * efi_memmap_walk() knows nothing about layout of memory across nodes. Find * out to which node a block of memory belongs. Ignore memory that we cannot * identify, and split blocks that run across multiple nodes. @@ -343,10 +404,10 @@ void show_mem(void) * Take this opportunity to round the start address up and the end address * down to page boundaries. */ -void call_pernode_memory(unsigned long start, unsigned long end, void *arg) +void call_pernode_memory(unsigned long start, unsigned long len, void *arg) { - unsigned long rs, re; - void (*func)(unsigned long, unsigned long, int, int); + unsigned long rs, re, end = start + len; + void (*func)(unsigned long, unsigned long, int); int i; start = PAGE_ALIGN(start); @@ -357,21 +418,127 @@ void call_pernode_memory(unsigned long s func = arg; if (!num_memblks) { - /* - * This machine doesn't have SRAT, so call func with - * nid=0, bank=0. - */ + /* No SRAT table, to assume one node (node 0) */ if (start < end) - (*func)(start, end - start, 0, 0); + (*func)(start, len, 0); return; } for (i = 0; i < num_memblks; i++) { rs = max(start, node_memblk[i].start_paddr); - re = min(end, node_memblk[i].start_paddr+node_memblk[i].size); + re = min(end, node_memblk[i].start_paddr + + node_memblk[i].size); if (rs < re) - (*func)(rs, re-rs, node_memblk[i].nid, - node_memblk[i].bank); + (*func)(rs, re - rs, node_memblk[i].nid); + + if (re == end) + break; + } +} + +/** + * count_node_pages - callback to build per-node memory info structures + * @start: physical start of range + * @len: length of range + * @node: node where this range resides + * + * Each node has it's own number of physical pages, DMAable pages, start, and + * end page frame number. This routine will be called by call_pernode_memory() + * for each piece of usable memory and will setup these values for each node. + * Very similar to build_maps(). + */ +static int count_node_pages(unsigned long start, unsigned long len, int node) +{ + unsigned long end = start + len; + + mem_data[node].num_physpages += len >> PAGE_SHIFT; + if (start <= __pa(MAX_DMA_ADDRESS)) + mem_data[node].num_dma_physpages += + (min(end, __pa(MAX_DMA_ADDRESS)) - start) >>PAGE_SHIFT; + start = GRANULEROUNDDOWN(start); + start = ORDERROUNDDOWN(start); + end = GRANULEROUNDUP(end); + mem_data[node].max_pfn = max(mem_data[node].max_pfn, + end >> PAGE_SHIFT); + mem_data[node].min_pfn = min(mem_data[node].min_pfn, + start >> PAGE_SHIFT); + + return 0; +} + +/** + * paging_init - setup page tables + * + * paging_init() sets up the page tables for each node of the system and frees + * the bootmem allocator memory for general use. + */ +void paging_init(void) +{ + unsigned long max_dma; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long max_gap, pfn_offset = 0; + int node; + + max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; + max_gap = 0; + efi_memmap_walk(find_largest_hole, &max_gap); + + /* so min() will work in count_node_pages */ + for (node = 0; node < numnodes; node++) + mem_data[node].min_pfn = ~0UL; + + efi_memmap_walk(filter_rsvd_memory, count_node_pages); + + for (node = 0; node < numnodes; node++) { + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + + num_physpages += mem_data[node].num_physpages; + + if (mem_data[node].min_pfn >= max_dma) { + /* All of this node's memory is above ZONE_DMA */ + zones_size[ZONE_NORMAL] = mem_data[node].max_pfn - + mem_data[node].min_pfn; + zholes_size[ZONE_NORMAL] = mem_data[node].max_pfn - + mem_data[node].min_pfn - + mem_data[node].num_physpages; + } else if (mem_data[node].max_pfn < max_dma) { + /* All of this node's memory is in ZONE_DMA */ + zones_size[ZONE_DMA] = mem_data[node].max_pfn - + mem_data[node].min_pfn; + zholes_size[ZONE_DMA] = mem_data[node].max_pfn - + mem_data[node].min_pfn - + mem_data[node].num_dma_physpages; + } else { + /* This node has memory in both zones */ + zones_size[ZONE_DMA] = max_dma - + mem_data[node].min_pfn; + zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - + mem_data[node].num_dma_physpages; + zones_size[ZONE_NORMAL] = mem_data[node].max_pfn - + max_dma; + zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] - + (mem_data[node].num_physpages - + mem_data[node].num_dma_physpages); + } + + if (node == 0) { + vmalloc_end -= + PAGE_ALIGN(max_low_pfn * sizeof(struct page)); + vmem_map = (struct page *) vmalloc_end; + + efi_memmap_walk(create_mem_map_page_table, 0); + printk("Virtual mem_map starts at 0x%p\n", vmem_map); + } + + pfn_offset = mem_data[node].min_pfn; + + free_area_init_node(node, NODE_DATA(node), + vmem_map + pfn_offset, zones_size, + pfn_offset, zholes_size); } + + zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } diff -prauN linux-2.6.0-test7/arch/ia64/mm/hugetlbpage.c wli-2.6.0-test7-bk5-36/arch/ia64/mm/hugetlbpage.c --- linux-2.6.0-test7/arch/ia64/mm/hugetlbpage.c 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/mm/hugetlbpage.c 2003-10-14 03:01:39.000000000 -0700 @@ -20,13 +20,46 @@ #define TASK_HPAGE_BASE (REGION_HPAGE << REGION_SHIFT) -static long htlbpagemem; -int htlbpage_max; -static long htlbzone_pages; +static long htlbpagemem; +int htlbpage_max; +static long htlbzone_pages; -static LIST_HEAD(htlbpage_freelist); +static struct list_head hugepage_freelists[MAX_NUMNODES]; static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; +static void enqueue_huge_page(struct page *page) +{ + list_add(&page->list, + &hugepage_freelists[page_zone(page)->zone_pgdat->node_id]); +} + +static struct page *dequeue_huge_page(void) +{ + int nid = numa_node_id(); + struct page *page = NULL; + + if (list_empty(&hugepage_freelists[nid])) { + for (nid = 0; nid < MAX_NUMNODES; ++nid) + if (!list_empty(&hugepage_freelists[nid])) + break; + } + if (nid >= 0 && nid < MAX_NUMNODES && + !list_empty(&hugepage_freelists[nid])) { + page = list_entry(hugepage_freelists[nid].next, struct page, list); + list_del(&page->list); + } + return page; +} + +static struct page *alloc_fresh_huge_page(void) +{ + static int nid = 0; + struct page *page; + page = alloc_pages_node(nid, GFP_HIGHUSER, HUGETLB_PAGE_ORDER); + nid = (nid + 1) % numnodes; + return page; +} + void free_huge_page(struct page *page); static struct page *alloc_hugetlb_page(void) @@ -35,13 +68,11 @@ static struct page *alloc_hugetlb_page(v struct page *page; spin_lock(&htlbpage_lock); - if (list_empty(&htlbpage_freelist)) { + page = dequeue_huge_page(); + if (!page) { spin_unlock(&htlbpage_lock); return NULL; } - - page = list_entry(htlbpage_freelist.next, struct page, list); - list_del(&page->list); htlbpagemem--; spin_unlock(&htlbpage_lock); set_page_count(page, 1); @@ -60,9 +91,9 @@ huge_pte_alloc (struct mm_struct *mm, un pte_t *pte = NULL; pgd = pgd_offset(mm, taddr); - pmd = pmd_alloc(mm, pgd, taddr); + pmd = pmd_alloc_map(mm, pgd, taddr); if (pmd) - pte = pte_alloc_map(mm, pmd, taddr); + pte = pte_alloc_map(mm, pgd, &pmd, taddr); return pte; } @@ -223,12 +254,12 @@ follow_huge_pmd(struct mm_struct *mm, un void free_huge_page(struct page *page) { BUG_ON(page_count(page)); - BUG_ON(page->mapping); + BUG_ON(page_mapping(page)); INIT_LIST_HEAD(&page->list); spin_lock(&htlbpage_lock); - list_add(&page->list, &htlbpage_freelist); + enqueue_huge_page(page); htlbpagemem++; spin_unlock(&htlbpage_lock); } @@ -371,7 +402,7 @@ int try_to_free_low(int count) map = NULL; spin_lock(&htlbpage_lock); - list_for_each(p, &htlbpage_freelist) { + list_for_each(p, &hugepage_freelists[0]) { if (map) { list_del(&map->list); update_and_free_page(map); @@ -408,11 +439,11 @@ int set_hugetlb_mem_size(int count) return (int)htlbzone_pages; if (lcount > 0) { /* Increase the mem size. */ while (lcount--) { - page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); + page = alloc_fresh_huge_page(); if (page == NULL) break; spin_lock(&htlbpage_lock); - list_add(&page->list, &htlbpage_freelist); + enqueue_huge_page(page); htlbpagemem++; htlbzone_pages++; spin_unlock(&htlbpage_lock); @@ -449,17 +480,18 @@ __setup("hugepages=", hugetlb_setup); static int __init hugetlb_init(void) { - int i, j; + int i; struct page *page; + for (i = 0; i < MAX_NUMNODES; ++i) + INIT_LIST_HEAD(&hugepage_freelists[i]); + for (i = 0; i < htlbpage_max; ++i) { - page = alloc_pages(__GFP_HIGHMEM, HUGETLB_PAGE_ORDER); + page = alloc_fresh_huge_page(); if (!page) break; - for (j = 0; j < HPAGE_SIZE/PAGE_SIZE; ++j) - SetPageReserved(&page[j]); spin_lock(&htlbpage_lock); - list_add(&page->list, &htlbpage_freelist); + enqueue_huge_page(page); spin_unlock(&htlbpage_lock); } htlbpage_max = htlbpagemem = htlbzone_pages = i; diff -prauN linux-2.6.0-test7/arch/ia64/mm/init.c wli-2.6.0-test7-bk5-36/arch/ia64/mm/init.c --- linux-2.6.0-test7/arch/ia64/mm/init.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/mm/init.c 2003-10-14 02:53:51.000000000 -0700 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -40,10 +41,8 @@ extern void ia64_tlb_init (void); unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL; #ifdef CONFIG_VIRTUAL_MEM_MAP -# define LARGE_GAP 0x40000000 /* Use virtual mem map if hole is > than this */ unsigned long vmalloc_end = VMALLOC_END_INIT; - static struct page *vmem_map; - static unsigned long num_dma_physpages; + struct page *vmem_map; #endif static int pgt_cache_water[2] = { 25, 50 }; @@ -232,10 +231,10 @@ put_kernel_page (struct page *page, unsi spin_lock(&init_mm.page_table_lock); { - pmd = pmd_alloc(&init_mm, pgd, address); + pmd = pmd_alloc_kernel(&init_mm, pgd, address); if (!pmd) goto out; - pte = pte_alloc_map(&init_mm, pmd, address); + pte = pte_alloc_map(&init_mm, pgd, &pmd, address); if (!pte) goto out; if (!pte_none(*pte)) { @@ -337,11 +336,12 @@ ia64_mmu_init (void *my_cpu_data) #ifdef CONFIG_VIRTUAL_MEM_MAP -static int +int create_mem_map_page_table (u64 start, u64 end, void *arg) { unsigned long address, start_page, end_page; struct page *map_start, *map_end; + int node; pgd_t *pgd; pmd_t *pmd; pte_t *pte; @@ -351,19 +351,20 @@ create_mem_map_page_table (u64 start, u6 start_page = (unsigned long) map_start & PAGE_MASK; end_page = PAGE_ALIGN((unsigned long) map_end); + node = paddr_to_nid(__pa(start)); for (address = start_page; address < end_page; address += PAGE_SIZE) { pgd = pgd_offset_k(address); if (pgd_none(*pgd)) - pgd_populate(&init_mm, pgd, alloc_bootmem_pages(PAGE_SIZE)); + pgd_populate(&init_mm, pgd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pmd = pmd_offset(pgd, address); if (pmd_none(*pmd)) - pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages(PAGE_SIZE)); + pmd_populate_kernel(&init_mm, pmd, alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)); pte = pte_offset_kernel(pmd, address); if (pte_none(*pte)) - set_pte(pte, pfn_pte(__pa(alloc_bootmem_pages(PAGE_SIZE)) >> PAGE_SHIFT, + set_pte(pte, pfn_pte(__pa(alloc_bootmem_pages_node(NODE_DATA(node), PAGE_SIZE)) >> PAGE_SHIFT, PAGE_KERNEL)); } return 0; @@ -433,17 +434,7 @@ ia64_pfn_valid (unsigned long pfn) return __get_user(byte, (char *) pfn_to_page(pfn)) == 0; } -static int -count_dma_pages (u64 start, u64 end, void *arg) -{ - unsigned long *count = arg; - - if (end <= MAX_DMA_ADDRESS) - *count += (end - start) >> PAGE_SHIFT; - return 0; -} - -static int +int find_largest_hole (u64 start, u64 end, void *arg) { u64 *max_gap = arg; @@ -460,103 +451,6 @@ find_largest_hole (u64 start, u64 end, v #endif /* CONFIG_VIRTUAL_MEM_MAP */ static int -count_pages (u64 start, u64 end, void *arg) -{ - unsigned long *count = arg; - - *count += (end - start) >> PAGE_SHIFT; - return 0; -} - -/* - * Set up the page tables. - */ - -#ifdef CONFIG_DISCONTIGMEM -void -paging_init (void) -{ - extern void discontig_paging_init(void); - - discontig_paging_init(); - efi_memmap_walk(count_pages, &num_physpages); - zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); -} -#else /* !CONFIG_DISCONTIGMEM */ -void -paging_init (void) -{ - unsigned long max_dma; - unsigned long zones_size[MAX_NR_ZONES]; -# ifdef CONFIG_VIRTUAL_MEM_MAP - unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long max_gap; -# endif - - /* initialize mem_map[] */ - - memset(zones_size, 0, sizeof(zones_size)); - - num_physpages = 0; - efi_memmap_walk(count_pages, &num_physpages); - - max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - -# ifdef CONFIG_VIRTUAL_MEM_MAP - memset(zholes_size, 0, sizeof(zholes_size)); - - num_dma_physpages = 0; - efi_memmap_walk(count_dma_pages, &num_dma_physpages); - - if (max_low_pfn < max_dma) { - zones_size[ZONE_DMA] = max_low_pfn; - zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages; - } else { - zones_size[ZONE_DMA] = max_dma; - zholes_size[ZONE_DMA] = max_dma - num_dma_physpages; - if (num_physpages > num_dma_physpages) { - zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; - zholes_size[ZONE_NORMAL] = ((max_low_pfn - max_dma) - - (num_physpages - num_dma_physpages)); - } - } - - max_gap = 0; - efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); - if (max_gap < LARGE_GAP) { - vmem_map = (struct page *) 0; - free_area_init_node(0, &contig_page_data, NULL, zones_size, 0, zholes_size); - mem_map = contig_page_data.node_mem_map; - } - else { - unsigned long map_size; - - /* allocate virtual_mem_map */ - - map_size = PAGE_ALIGN(max_low_pfn * sizeof(struct page)); - vmalloc_end -= map_size; - vmem_map = (struct page *) vmalloc_end; - efi_memmap_walk(create_mem_map_page_table, 0); - - free_area_init_node(0, &contig_page_data, vmem_map, zones_size, 0, zholes_size); - - mem_map = contig_page_data.node_mem_map; - printk("Virtual mem_map starts at 0x%p\n", mem_map); - } -# else /* !CONFIG_VIRTUAL_MEM_MAP */ - if (max_low_pfn < max_dma) - zones_size[ZONE_DMA] = max_low_pfn; - else { - zones_size[ZONE_DMA] = max_dma; - zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; - } - free_area_init(zones_size); -# endif /* !CONFIG_VIRTUAL_MEM_MAP */ - zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); -} -#endif /* !CONFIG_DISCONTIGMEM */ - -static int count_reserved_pages (u64 start, u64 end, void *arg) { unsigned long num_reserved = 0; diff -prauN linux-2.6.0-test7/arch/ia64/sn/io/machvec/pci_bus_cvlink.c wli-2.6.0-test7-bk5-36/arch/ia64/sn/io/machvec/pci_bus_cvlink.c --- linux-2.6.0-test7/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/sn/io/machvec/pci_bus_cvlink.c 2003-10-14 02:49:46.000000000 -0700 @@ -867,6 +867,9 @@ sn_pci_init (void) int i = 0; struct pci_controller *controller; + if (!ia64_platform_is("sn2")) + return 0; + /* * set pci_raw_ops, etc. */ diff -prauN linux-2.6.0-test7/arch/ia64/sn/io/sn2/ml_SN_intr.c wli-2.6.0-test7-bk5-36/arch/ia64/sn/io/sn2/ml_SN_intr.c --- linux-2.6.0-test7/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/sn/io/sn2/ml_SN_intr.c 2003-10-14 02:49:46.000000000 -0700 @@ -285,7 +285,6 @@ static cpuid_t intr_cpu_choose_node(void cpuid_t intr_heuristic(vertex_hdl_t dev, int req_bit, int *resp_bit) { cpuid_t cpuid; - cpuid_t candidate = CPU_NONE; vertex_hdl_t pconn_vhdl; pcibr_soft_t pcibr_soft; int bit; @@ -293,30 +292,32 @@ cpuid_t intr_heuristic(vertex_hdl_t dev, /* XXX: gross layering violation.. */ if (hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) { pcibr_soft = pcibr_soft_get(pconn_vhdl); - if (pcibr_soft && pcibr_soft->bsi_err_intr) - candidate = ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid; - } - - if (candidate != CPU_NONE) { - /* - * The cpu was chosen already when we assigned - * the error interrupt. - */ - bit = intr_reserve_level(candidate, req_bit); - if (bit >= 0) { - *resp_bit = bit; - return candidate; + if (pcibr_soft && pcibr_soft->bsi_err_intr) { + /* + * The cpu was chosen already when we assigned + * the error interrupt. + */ + cpuid = ((hub_intr_t)pcibr_soft->bsi_err_intr)->i_cpuid; + goto done; } - - printk("Cannot target interrupt to target node (%ld).\n",candidate); - return CPU_NONE; } /* * Need to choose one. Try the controlling c-brick first. */ cpuid = intr_cpu_choose_from_node(master_node_get(dev)); - if (cpuid != CPU_NONE) - return cpuid; - return intr_cpu_choose_node(); + if (cpuid == CPU_NONE) + cpuid = intr_cpu_choose_node(); + + done: + if (cpuid != CPU_NONE) { + bit = intr_reserve_level(cpuid, req_bit); + if (bit >= 0) { + *resp_bit = bit; + return cpuid; + } + } + + printk("Cannot target interrupt to target cpu (%ld).\n", cpuid); + return CPU_NONE; } diff -prauN linux-2.6.0-test7/arch/ia64/sn/kernel/setup.c wli-2.6.0-test7-bk5-36/arch/ia64/sn/kernel/setup.c --- linux-2.6.0-test7/arch/ia64/sn/kernel/setup.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ia64/sn/kernel/setup.c 2003-10-14 02:49:46.000000000 -0700 @@ -147,7 +147,6 @@ char drive_info[4*16]; * Sets up an initial console to aid debugging. Intended primarily * for bringup. See start_kernel() in init/main.c. */ -#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM) void __init early_sn_setup(void) @@ -189,7 +188,6 @@ early_sn_setup(void) printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address); } } -#endif /* CONFIG_IA64_EARLY_PRINTK_SGI_SN */ #ifdef CONFIG_IA64_MCA extern int platform_intr_list[]; diff -prauN linux-2.6.0-test7/arch/m68k/kernel/head.S wli-2.6.0-test7-bk5-36/arch/m68k/kernel/head.S --- linux-2.6.0-test7/arch/m68k/kernel/head.S 2003-10-08 12:24:52.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/m68k/kernel/head.S 2003-10-14 02:53:51.000000000 -0700 @@ -110,7 +110,7 @@ * * These routines are used by other mmu routines to get a pointer into * a table, if necessary a new table is allocated. These routines are working - * basically like pmd_alloc() and pte_alloc() in . The root + * basically like pmd_alloc_map() and pte_alloc_map() in . The root * table needs of course only to be allocated once in mmu_get_root_table_entry, * so that here also some mmu specific initialization is done. The second page * at the start of the kernel (the first page is unmapped later) is used for diff -prauN linux-2.6.0-test7/arch/m68k/mm/kmap.c wli-2.6.0-test7-bk5-36/arch/m68k/mm/kmap.c --- linux-2.6.0-test7/arch/m68k/mm/kmap.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/m68k/mm/kmap.c 2003-10-14 02:53:51.000000000 -0700 @@ -189,7 +189,7 @@ void *__ioremap(unsigned long physaddr, printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr); #endif pgd_dir = pgd_offset_k(virtaddr); - pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr); + pmd_dir = pmd_alloc_kernel(&init_mm, pgd_dir, virtaddr); if (!pmd_dir) { printk("ioremap: no mem for pmd_dir\n"); return NULL; diff -prauN linux-2.6.0-test7/arch/m68k/sun3x/dvma.c wli-2.6.0-test7-bk5-36/arch/m68k/sun3x/dvma.c --- linux-2.6.0-test7/arch/m68k/sun3x/dvma.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/m68k/sun3x/dvma.c 2003-10-14 02:53:51.000000000 -0700 @@ -102,7 +102,7 @@ inline int dvma_map_cpu(unsigned long ka pmd_t *pmd; unsigned long end2; - if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) { + if((pmd = pmd_alloc_kernel(&init_mm, pgd, vaddr)) == NULL) { ret = -ENOMEM; goto out; } diff -prauN linux-2.6.0-test7/arch/mips/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/mips/mm/ioremap.c --- linux-2.6.0-test7/arch/mips/mm/ioremap.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/mips/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -81,7 +81,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/parisc/kernel/cache.c wli-2.6.0-test7-bk5-36/arch/parisc/kernel/cache.c --- linux-2.6.0-test7/arch/parisc/kernel/cache.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/parisc/kernel/cache.c 2003-10-14 03:01:39.000000000 -0700 @@ -68,7 +68,7 @@ update_mmu_cache(struct vm_area_struct * { struct page *page = pte_page(pte); - if (VALID_PAGE(page) && page->mapping && + if (VALID_PAGE(page) && page_mapping(page) && test_bit(PG_dcache_dirty, &page->flags)) { flush_kernel_dcache_page(page_address(page)); @@ -234,15 +234,17 @@ void __flush_dcache_page(struct page *pa flush_kernel_dcache_page(page_address(page)); - if (!page->mapping) + if (!page_mapping(page)) return; /* check shared list first if it's not empty...it's usually * the shortest */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each_rcu(l, &page->mapping->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; mpnt = list_entry(l, struct vm_area_struct, shared); + if (mpnt->vm_flags & VM_DEAD) + continue; /* * If this VMA is not in our MM, we can ignore it. diff -prauN linux-2.6.0-test7/arch/parisc/kernel/pci-dma.c wli-2.6.0-test7-bk5-36/arch/parisc/kernel/pci-dma.c --- linux-2.6.0-test7/arch/parisc/kernel/pci-dma.c 2003-10-08 12:24:45.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/parisc/kernel/pci-dma.c 2003-10-14 02:53:51.000000000 -0700 @@ -133,7 +133,7 @@ static inline int map_uncached_pages(uns do { pmd_t *pmd; - pmd = pmd_alloc(NULL, dir, vaddr); + pmd = pmd_alloc_kernel(NULL, dir, vaddr); if (!pmd) return -ENOMEM; if (map_pmd_uncached(pmd, vaddr, end - vaddr, &paddr)) diff -prauN linux-2.6.0-test7/arch/parisc/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/parisc/mm/ioremap.c --- linux-2.6.0-test7/arch/parisc/mm/ioremap.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/parisc/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -77,7 +77,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(dir, address); + pmd = pmd_alloc_kernel(dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/ppc/8260_io/Kconfig wli-2.6.0-test7-bk5-36/arch/ppc/8260_io/Kconfig --- linux-2.6.0-test7/arch/ppc/8260_io/Kconfig 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/8260_io/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -57,14 +57,5 @@ config FCC_QS6612 bool "QS6612" endchoice - -comment "Generic MPC8260 Options" - -config DCACHE_DISABLE - bool "Disable data cache" - help - This option allows you to run the kernel with data cache disabled. - Say Y if you experience CPM lock-ups. - endmenu diff -prauN linux-2.6.0-test7/arch/ppc/Makefile wli-2.6.0-test7-bk5-36/arch/ppc/Makefile --- linux-2.6.0-test7/arch/ppc/Makefile 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -65,7 +65,13 @@ uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot)/images $(boot)/images/$@ define archhelp + @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/images/zImage.*)' @echo ' uImage - Create a bootable image for U-Boot / PPCBoot' + @echo ' install - Install kernel using' + @echo ' (your) ~/bin/installkernel or' + @echo ' (distribution) /sbin/installkernel or' + @echo ' install to $$(INSTALL_PATH) and run lilo' + @echo ' *_defconfig - Select default config from arch/$(ARCH)/ppc/configs' endef archclean: diff -prauN linux-2.6.0-test7/arch/ppc/boot/common/ns16550.c wli-2.6.0-test7-bk5-36/arch/ppc/boot/common/ns16550.c --- linux-2.6.0-test7/arch/ppc/boot/common/ns16550.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/boot/common/ns16550.c 2003-10-14 02:49:46.000000000 -0700 @@ -3,6 +3,8 @@ */ #include +#include +#include #include #include #include diff -prauN linux-2.6.0-test7/arch/ppc/boot/of1275/map.c wli-2.6.0-test7-bk5-36/arch/ppc/boot/of1275/map.c --- linux-2.6.0-test7/arch/ppc/boot/of1275/map.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/boot/of1275/map.c 2003-10-14 02:49:46.000000000 -0700 @@ -23,11 +23,10 @@ map(unsigned int phys, unsigned int virt char *method; ihandle mmu_ihandle; int misc; - unsigned int phys; - unsigned int virt; unsigned int size; + unsigned int virt; + unsigned int phys; int ret0; - int ret1; } args; if (of_prom_mmu == 0) { @@ -36,10 +35,10 @@ map(unsigned int phys, unsigned int virt } args.service = "call-method"; args.nargs = 6; - args.nret = 2; + args.nret = 1; args.method = "map"; args.mmu_ihandle = of_prom_mmu; - args.misc = -1; + args.misc = 0; args.phys = phys; args.virt = virt; args.size = size; diff -prauN linux-2.6.0-test7/arch/ppc/boot/openfirmware/coffmain.c wli-2.6.0-test7-bk5-36/arch/ppc/boot/openfirmware/coffmain.c --- linux-2.6.0-test7/arch/ppc/boot/openfirmware/coffmain.c 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/boot/openfirmware/coffmain.c 2003-10-14 02:49:46.000000000 -0700 @@ -38,9 +38,9 @@ static char heap[SCRATCH_SIZE]; static unsigned long ram_start = 0; static unsigned long ram_end = 0x1000000; -static unsigned long prog_start = 0x800000; -static unsigned long prog_size = 0x800000; +static unsigned long prog_start = 0x900000; +static unsigned long prog_size = 0x700000; typedef void (*kernel_start_t)(int, int, void *); diff -prauN linux-2.6.0-test7/arch/ppc/configs/TQM8260_defconfig wli-2.6.0-test7-bk5-36/arch/ppc/configs/TQM8260_defconfig --- linux-2.6.0-test7/arch/ppc/configs/TQM8260_defconfig 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/configs/TQM8260_defconfig 2003-10-14 02:49:46.000000000 -0700 @@ -469,11 +469,6 @@ CONFIG_FCC2_ENET=y # CONFIG_FCC3_ENET is not set # -# Generic MPC8260 Options -# -CONFIG_DCACHE_DISABLE=y - -# # USB support # # CONFIG_USB_GADGET is not set diff -prauN linux-2.6.0-test7/arch/ppc/configs/est8260_defconfig wli-2.6.0-test7-bk5-36/arch/ppc/configs/est8260_defconfig --- linux-2.6.0-test7/arch/ppc/configs/est8260_defconfig 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/configs/est8260_defconfig 2003-10-14 02:49:46.000000000 -0700 @@ -461,11 +461,6 @@ CONFIG_SCC_ENET=y CONFIG_SCC_CONSOLE=y # -# Generic MPC8260 Options -# -# CONFIG_DCACHE_DISABLE is not set - -# # USB support # # CONFIG_USB_GADGET is not set diff -prauN linux-2.6.0-test7/arch/ppc/kernel/cpu_setup_6xx.S wli-2.6.0-test7-bk5-36/arch/ppc/kernel/cpu_setup_6xx.S --- linux-2.6.0-test7/arch/ppc/kernel/cpu_setup_6xx.S 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/kernel/cpu_setup_6xx.S 2003-10-14 02:49:46.000000000 -0700 @@ -75,11 +75,7 @@ _GLOBAL(__setup_cpu_745x) setup_common_caches: mfspr r11,HID0 andi. r0,r11,HID0_DCE -#ifdef CONFIG_DCACHE_DISABLE - ori r11,r11,HID0_ICE -#else ori r11,r11,HID0_ICE|HID0_DCE -#endif ori r8,r11,HID0_ICFI bne 1f /* don't invalidate the D-cache */ ori r8,r8,HID0_DCI /* unless it wasn't enabled */ diff -prauN linux-2.6.0-test7/arch/ppc/kernel/head.S wli-2.6.0-test7-bk5-36/arch/ppc/kernel/head.S --- linux-2.6.0-test7/arch/ppc/kernel/head.S 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/kernel/head.S 2003-10-14 02:49:46.000000000 -0700 @@ -181,26 +181,8 @@ __after_mmu_off: bl setup_disp_bat #endif #else /* CONFIG_POWER4 */ -/* - * Load up the SDR1 and segment register values now - * since we don't have the BATs. - * Also make sure we are running in 32-bit mode. - */ bl reloc_offset - addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ - lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ - mtspr SDR1,r14 - slbia - lis r4,0x2000 /* set pseudo-segment reg 12 */ - ori r5,r4,0x0ccc - mtsr 12,r5 - ori r4,r4,0x0888 /* set pseudo-segment reg 8 */ - mtsr 8,r4 /* (for access to serial port) */ - mfmsr r0 - clrldi r0,r0,1 - sync - mtmsr r0 - isync + bl initial_mm_power4 #endif /* CONFIG_POWER4 */ /* @@ -1637,6 +1619,34 @@ setup_disp_bat: #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ #else /* CONFIG_POWER4 */ +/* + * Load up the SDR1 and segment register values now + * since we don't have the BATs. + * Also make sure we are running in 32-bit mode. + */ + +initial_mm_power4: + addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ + lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ + mtspr SDR1,r14 + slbia + lis r4,0x2000 /* set pseudo-segment reg 12 */ + ori r5,r4,0x0ccc + mtsr 12,r5 + ori r5,r4,0x0888 /* set pseudo-segment reg 8 */ + mtsr 8,r5 /* (for access to serial port) */ + ori r5,r4,0x0999 /* set pseudo-segment reg 8 */ + mtsr 9,r5 /* (for access to screen) */ + mfmsr r0 + clrldi r0,r0,1 + sync + mtmsr r0 + isync + blr + +/* + * On 970 (G5), we pre-set a few bits in HID0 & HID1 + */ ppc970_setup_hid: li r0,0 sync diff -prauN linux-2.6.0-test7/arch/ppc/kernel/ppc_ksyms.c wli-2.6.0-test7-bk5-36/arch/ppc/kernel/ppc_ksyms.c --- linux-2.6.0-test7/arch/ppc/kernel/ppc_ksyms.c 2003-10-08 12:24:44.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/kernel/ppc_ksyms.c 2003-10-14 02:49:46.000000000 -0700 @@ -123,7 +123,7 @@ EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strcasecmp); EXPORT_SYMBOL(__div64_32); -/* EXPORT_SYMBOL(csum_partial); already in net/netsyms.c */ +EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); EXPORT_SYMBOL(ip_fast_csum); EXPORT_SYMBOL(csum_tcpudp_magic); @@ -367,11 +367,17 @@ EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(handle_mm_fault); /* For MOL */ EXPORT_SYMBOL_NOVERS(disarm_decr); +extern long mol_trampoline; +EXPORT_SYMBOL(mol_trampoline); /* For MOL */ #ifdef CONFIG_PPC_STD_MMU EXPORT_SYMBOL(flush_hash_pages); /* For MOL */ +#ifdef CONFIG_SMP +extern int mmu_hash_lock; +EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ +#endif /* CONFIG_SMP */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); -#endif +#endif /* CONFIG_PPC_STD_MMU */ EXPORT_SYMBOL(cur_cpu_spec); #ifdef CONFIG_PPC_PMAC extern unsigned long agp_special_page; diff -prauN linux-2.6.0-test7/arch/ppc/kernel/process.c wli-2.6.0-test7-bk5-36/arch/ppc/kernel/process.c --- linux-2.6.0-test7/arch/ppc/kernel/process.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/kernel/process.c 2003-10-14 02:49:46.000000000 -0700 @@ -56,6 +56,7 @@ static struct files_struct init_files = static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_SYMBOL(init_mm); /* this is 8kB-aligned so we can get to the thread_info struct at the base of it from the stack pointer with 1 integer instruction. */ @@ -65,6 +66,7 @@ union thread_union init_thread_union /* initial task structure */ struct task_struct init_task = INIT_TASK(init_task); +EXPORT_SYMBOL(init_task); /* only used to get secondary processor up */ struct task_struct *current_set[NR_CPUS] = {&init_task, }; diff -prauN linux-2.6.0-test7/arch/ppc/kernel/setup.c wli-2.6.0-test7-bk5-36/arch/ppc/kernel/setup.c --- linux-2.6.0-test7/arch/ppc/kernel/setup.c 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/kernel/setup.c 2003-10-14 02:49:46.000000000 -0700 @@ -171,12 +171,12 @@ int show_cpuinfo(struct seq_file *m, voi return 0; pvr = cpu_data[i].pvr; lpj = cpu_data[i].loops_per_jiffy; - seq_printf(m, "processor\t: %d\n", i); #else pvr = mfspr(PVR); lpj = loops_per_jiffy; #endif + seq_printf(m, "processor\t: %d\n", i); seq_printf(m, "cpu\t\t: "); if (cur_cpu_spec[i]->pvr_mask) diff -prauN linux-2.6.0-test7/arch/ppc/mm/hashtable.S wli-2.6.0-test7-bk5-36/arch/ppc/mm/hashtable.S --- linux-2.6.0-test7/arch/ppc/mm/hashtable.S 2003-10-08 12:24:32.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/mm/hashtable.S 2003-10-14 02:49:46.000000000 -0700 @@ -417,6 +417,21 @@ _GLOBAL(hash_page_patch_C) lwz r6,next_slot@l(r4) addi r6,r6,PTE_SIZE andi. r6,r6,7*PTE_SIZE +#ifdef CONFIG_POWER4 + /* + * Since we don't have BATs on POWER4, we rely on always having + * PTEs in the hash table to map the hash table and the code + * that manipulates it in virtual mode, namely flush_hash_page and + * flush_hash_segments. Otherwise we can get a DSI inside those + * routines which leads to a deadlock on the hash_table_lock on + * SMP machines. We avoid this by never overwriting the first + * PTE of each PTEG if it is already valid. + * -- paulus. + */ + bne 102f + li r6,PTE_SIZE +102: +#endif /* CONFIG_POWER4 */ stw r6,next_slot@l(r4) add r4,r3,r6 diff -prauN linux-2.6.0-test7/arch/ppc/mm/init.c wli-2.6.0-test7-bk5-36/arch/ppc/mm/init.c --- linux-2.6.0-test7/arch/ppc/mm/init.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/mm/init.c 2003-10-14 03:01:39.000000000 -0700 @@ -477,14 +477,14 @@ void __init mem_init(void) printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page); #endif - /* Make sure all our pagetable pages have page->mapping + /* Make sure all our pagetable pages have page_mapping(page) and page->index set correctly. */ for (addr = KERNELBASE; addr != 0; addr += PGDIR_SIZE) { struct page *pg; pmd_t *pmd = pmd_offset(pgd_offset_k(addr), addr); if (pmd_present(*pmd)) { pg = pmd_page(*pmd); - pg->mapping = (void *) &init_mm; + set_page_mapping(pg, &init_mm); pg->index = addr; } } diff -prauN linux-2.6.0-test7/arch/ppc/mm/ppc_mmu.c wli-2.6.0-test7-bk5-36/arch/ppc/mm/ppc_mmu.c --- linux-2.6.0-test7/arch/ppc/mm/ppc_mmu.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/mm/ppc_mmu.c 2003-10-14 02:49:46.000000000 -0700 @@ -211,6 +211,17 @@ void __init MMU_init_hw(void) #define MIN_N_HPTEG 1024 /* min 64kB hash table */ #endif +#ifdef CONFIG_POWER4 + /* The hash table has already been allocated and initialized + in prom.c */ + n_hpteg = Hash_size >> LG_HPTEG_SIZE; + lg_n_hpteg = __ilog2(n_hpteg); + + /* Remove the hash table from the available memory */ + if (Hash) + reserve_phys_mem(__pa(Hash), Hash_size); + +#else /* CONFIG_POWER4 */ /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. * This is less than the recommended amount, but then @@ -224,13 +235,7 @@ void __init MMU_init_hw(void) ++lg_n_hpteg; /* round up if not power of 2 */ n_hpteg = 1 << lg_n_hpteg; } - Hash_size = n_hpteg << LG_HPTEG_SIZE; - Hash_mask = n_hpteg - 1; - hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); - mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; - if (lg_n_hpteg > 16) - mb2 = 16 - LG_HPTEG_SIZE; /* * Find some memory for the hash table. @@ -240,6 +245,7 @@ void __init MMU_init_hw(void) cacheable_memzero(Hash, Hash_size); _SDR1 = __pa(Hash) | SDR1_LOW_BITS; Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); +#endif /* CONFIG_POWER4 */ printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", total_memory >> 20, Hash_size >> 10, Hash); @@ -249,6 +255,12 @@ void __init MMU_init_hw(void) * Patch up the instructions in hashtable.S:create_hpte */ if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); + Hash_mask = n_hpteg - 1; + hmask = Hash_mask >> (16 - LG_HPTEG_SIZE); + mb2 = mb = 32 - LG_HPTEG_SIZE - lg_n_hpteg; + if (lg_n_hpteg > 16) + mb2 = 16 - LG_HPTEG_SIZE; + hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) | ((unsigned int)(Hash) >> 16); hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6); diff -prauN linux-2.6.0-test7/arch/ppc/platforms/pmac_smp.c wli-2.6.0-test7-bk5-36/arch/ppc/platforms/pmac_smp.c --- linux-2.6.0-test7/arch/ppc/platforms/pmac_smp.c 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/platforms/pmac_smp.c 2003-10-14 02:49:46.000000000 -0700 @@ -51,6 +51,7 @@ #include #include #include +#include /* * Powersurge (old powermac SMP) support. @@ -108,9 +109,16 @@ static volatile u32 *psurge_start; /* what sort of powersurge board we have */ static int psurge_type = PSURGE_NONE; +/* L2 and L3 cache settings to pass from CPU0 to CPU1 */ volatile static long int core99_l2_cache; volatile static long int core99_l3_cache; +/* Timebase freeze GPIO */ +static unsigned int core99_tb_gpio; + +/* Sync flag for HW tb sync */ +static volatile int sec_tb_reset = 0; + static void __init core99_init_caches(int cpu) { @@ -380,7 +388,6 @@ static void __init smp_psurge_kick_cpu(i */ static void __init psurge_dual_sync_tb(int cpu_nr) { - static volatile int sec_tb_reset = 0; int t; set_dec(tb_ticks_per_jiffy); @@ -408,8 +415,15 @@ smp_psurge_setup_cpu(int cpu_nr) { if (cpu_nr == 0) { - if (num_online_cpus() < 2) + /* If we failed to start the second CPU, we should still + * send it an IPI to start the timebase & DEC or we might + * have them stuck. + */ + if (num_online_cpus() < 2) { + if (psurge_type == PSURGE_DUAL) + psurge_set_ipi(1); return; + } /* reset the entry point so if we get another intr we won't * try to startup again */ out_be32(psurge_start, 0x100); @@ -421,19 +435,42 @@ smp_psurge_setup_cpu(int cpu_nr) psurge_dual_sync_tb(cpu_nr); } +void __init +smp_psurge_take_timebase(void) +{ + /* Dummy implementation */ +} + +void __init +smp_psurge_give_timebase(void) +{ + /* Dummy implementation */ +} + static int __init smp_core99_probe(void) { + extern int powersave_nap; struct device_node *cpus; int i, ncpus = 1; - extern int powersave_nap; + u32 *tbprop; if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); cpus = find_type_devices("cpu"); - if (cpus) - while ((cpus = cpus->next) != NULL) - ++ncpus; + if (cpus == NULL) + return 0; + + tbprop = (u32 *)get_property(cpus, "timebase-enable", NULL); + if (tbprop) + core99_tb_gpio = *tbprop; + else + core99_tb_gpio = KL_GPIO_TB_ENABLE; + + while ((cpus = cpus->next) != NULL) + ++ncpus; + printk("smp_core99_probe: found %d cpus\n", ncpus); + if (ncpus > 1) { openpic_request_IPIs(); for (i = 1; i < ncpus; ++i) @@ -517,14 +554,59 @@ smp_core99_setup_cpu(int cpu_nr) if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); } +void __init +smp_core99_take_timebase(void) +{ + /* Secondary processor "takes" the timebase by freezing + * it, resetting its local TB and telling CPU 0 to go on + */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + mb(); + + set_dec(tb_ticks_per_jiffy); + set_tb(0, 0); + last_jiffy_stamp(smp_processor_id()) = 0; + + mb(); + sec_tb_reset = 1; +} + +void __init +smp_core99_give_timebase(void) +{ + unsigned int t; + + /* Primary processor waits for secondary to have frozen + * the timebase, resets local TB, and kick timebase again + */ + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 1000; t > 0 && !sec_tb_reset; --t) + udelay(1000); + if (t == 0) + printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); + + set_dec(tb_ticks_per_jiffy); + set_tb(0, 0); + last_jiffy_stamp(smp_processor_id()) = 0; + mb(); + + /* Now, restart the timebase by leaving the GPIO to an open collector */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + + smp_tb_synchronized = 1; +} + + /* PowerSurge-style Macs */ struct smp_ops_t psurge_smp_ops __pmacdata = { .message_pass = smp_psurge_message_pass, .probe = smp_psurge_probe, .kick_cpu = smp_psurge_kick_cpu, .setup_cpu = smp_psurge_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, + .give_timebase = smp_psurge_give_timebase, + .take_timebase = smp_psurge_take_timebase, }; /* Core99 Macs (dual G4s) */ @@ -533,6 +615,6 @@ struct smp_ops_t core99_smp_ops __pmacda .probe = smp_core99_probe, .kick_cpu = smp_core99_kick_cpu, .setup_cpu = smp_core99_setup_cpu, - .give_timebase = smp_generic_give_timebase, - .take_timebase = smp_generic_take_timebase, + .give_timebase = smp_core99_give_timebase, + .take_timebase = smp_core99_take_timebase, }; diff -prauN linux-2.6.0-test7/arch/ppc/platforms/pmac_time.c wli-2.6.0-test7-bk5-36/arch/ppc/platforms/pmac_time.c --- linux-2.6.0-test7/arch/ppc/platforms/pmac_time.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/platforms/pmac_time.c 2003-10-14 02:49:46.000000000 -0700 @@ -166,7 +166,7 @@ via_calibrate_decr(void) { struct device_node *vias; volatile unsigned char *via; - int count = VIA_TIMER_FREQ_6 / HZ; + int count = VIA_TIMER_FREQ_6 / 100; unsigned int dstart, dend; vias = find_devices("via-cuda"); @@ -196,7 +196,7 @@ via_calibrate_decr(void) ; dend = get_dec(); - tb_ticks_per_jiffy = (dstart - dend) / 6; + tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100)); tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", @@ -260,7 +260,9 @@ pmac_calibrate_decr(void) * calibration. That's better since the VIA itself seems * to be slightly off. --BenH */ - if (!machine_is_compatible("MacRISC2")) + if (!machine_is_compatible("MacRISC2") && + !machine_is_compatible("MacRISC3") && + !machine_is_compatible("MacRISC4")) if (via_calibrate_decr()) return; diff -prauN linux-2.6.0-test7/arch/ppc/syslib/of_device.c wli-2.6.0-test7-bk5-36/arch/ppc/syslib/of_device.c --- linux-2.6.0-test7/arch/ppc/syslib/of_device.c 2003-10-08 12:24:52.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc/syslib/of_device.c 2003-10-14 02:49:46.000000000 -0700 @@ -97,9 +97,9 @@ static int of_device_probe(struct device static int of_device_remove(struct device *dev) { struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - if (drv && drv->remove) + if (dev->driver && drv->remove) drv->remove(of_dev); return 0; } @@ -107,10 +107,10 @@ static int of_device_remove(struct devic static int of_device_suspend(struct device *dev, u32 state) { struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); int error = 0; - if (drv && drv->suspend) + if (dev->driver && drv->suspend) error = drv->suspend(of_dev, state); return error; } @@ -118,10 +118,10 @@ static int of_device_suspend(struct devi static int of_device_resume(struct device * dev) { struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(of_dev->dev.driver); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); int error = 0; - if (drv && drv->resume) + if (dev->driver && drv->resume) error = drv->resume(of_dev); return error; } diff -prauN linux-2.6.0-test7/arch/ppc64/mm/init.c wli-2.6.0-test7-bk5-36/arch/ppc64/mm/init.c --- linux-2.6.0-test7/arch/ppc64/mm/init.c 2003-10-08 12:24:14.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/ppc64/mm/init.c 2003-10-14 02:53:51.000000000 -0700 @@ -205,7 +205,7 @@ static void map_io_page(unsigned long ea if (mem_init_done) { spin_lock(&ioremap_mm.page_table_lock); pgdp = pgd_offset_i(ea); - pmdp = pmd_alloc(&ioremap_mm, pgdp, ea); + pmdp = pmd_alloc_kernel(&ioremap_mm, pgdp, ea); ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); pa = absolute_to_phys(pa); diff -prauN linux-2.6.0-test7/arch/s390/kernel/compat_exec.c wli-2.6.0-test7-bk5-36/arch/s390/kernel/compat_exec.c --- linux-2.6.0-test7/arch/s390/kernel/compat_exec.c 2003-10-08 12:24:43.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/s390/kernel/compat_exec.c 2003-10-14 02:58:33.000000000 -0700 @@ -81,7 +81,8 @@ int setup_arg_pages32(struct linux_binpr struct page *page = bprm->page[i]; if (page) { bprm->page[i] = NULL; - put_dirty_page(current,page,stack_base,PAGE_COPY); + put_dirty_page(current, mpnt, page, + stack_base, PAGE_COPY); } stack_base += PAGE_SIZE; } diff -prauN linux-2.6.0-test7/arch/s390/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/s390/mm/ioremap.c --- linux-2.6.0-test7/arch/s390/mm/ioremap.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/s390/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -83,7 +83,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/arch/sh/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/sh/mm/ioremap.c --- linux-2.6.0-test7/arch/sh/mm/ioremap.c 2003-10-08 12:24:15.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sh/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -45,7 +45,7 @@ static inline void remap_area_pte(pte_t } while (address && (address < end)); } -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, +static inline int remap_area_pmd(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long phys_addr, unsigned long flags) { unsigned long end; @@ -83,11 +83,11 @@ int remap_area_pages(unsigned long addre spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_map(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; - if (remap_area_pmd(pmd, address, end - address, + if (remap_area_pmd(dir, pmd, address, end - address, phys_addr + address, flags)) break; error = 0; diff -prauN linux-2.6.0-test7/arch/sparc/mm/generic.c wli-2.6.0-test7-bk5-36/arch/sparc/mm/generic.c --- linux-2.6.0-test7/arch/sparc/mm/generic.c 2003-10-08 12:24:44.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc/mm/generic.c 2003-10-14 02:53:51.000000000 -0700 @@ -67,7 +67,7 @@ static inline void io_remap_pte_range(pt } while (address < end); } -static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size, +static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long offset, pgprot_t prot, int space) { unsigned long end; @@ -78,7 +78,7 @@ static inline int io_remap_pmd_range(pmd end = PGDIR_SIZE; offset -= address; do { - pte_t * pte = pte_alloc_map(current->mm, pmd, address); + pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address); if (!pte) return -ENOMEM; io_remap_pte_range(pte, address, end - address, address + offset, prot, space); @@ -103,11 +103,11 @@ int io_remap_page_range(struct vm_area_s spin_lock(&mm->page_table_lock); while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); + pmd_t *pmd = pmd_alloc_map(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; - error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space); + error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space); if (error) break; from = (from + PGDIR_SIZE) & PGDIR_MASK; diff -prauN linux-2.6.0-test7/arch/sparc/mm/srmmu.c wli-2.6.0-test7-bk5-36/arch/sparc/mm/srmmu.c --- linux-2.6.0-test7/arch/sparc/mm/srmmu.c 2003-10-08 12:24:14.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc/mm/srmmu.c 2003-10-14 02:53:51.000000000 -0700 @@ -2180,7 +2180,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); BTFIXUPSET_SETHI(none_mask, 0xF0000000); @@ -2212,7 +2212,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pmd_fast, srmmu_pmd_free, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__pmd_alloc_one, srmmu_pmd_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pgd_fast, srmmu_free_pgd_fast, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(get_pgd_fast, srmmu_get_pgd_fast, BTFIXUPCALL_NORM); diff -prauN linux-2.6.0-test7/arch/sparc/mm/sun4c.c wli-2.6.0-test7-bk5-36/arch/sparc/mm/sun4c.c --- linux-2.6.0-test7/arch/sparc/mm/sun4c.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc/mm/sun4c.c 2003-10-14 02:53:51.000000000 -0700 @@ -2211,7 +2211,7 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(__pmd_alloc_one, sun4c_pmd_alloc_one, BTFIXUPCALL_RETO0); BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(get_pgd_fast, sun4c_get_pgd_fast, BTFIXUPCALL_NORM); @@ -2252,5 +2252,5 @@ void __init ld_mmu_sun4c(void) /* These should _never_ get called with two level tables. */ BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); - BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); + BTFIXUPSET_CALL(__pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); } diff -prauN linux-2.6.0-test7/arch/sparc64/defconfig wli-2.6.0-test7-bk5-36/arch/sparc64/defconfig --- linux-2.6.0-test7/arch/sparc64/defconfig 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/defconfig 2003-10-14 02:49:46.000000000 -0700 @@ -799,11 +799,9 @@ CONFIG_ATM_TCP=m # CONFIG_ATM_ENI is not set # CONFIG_ATM_FIRESTREAM is not set # CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set # CONFIG_ATM_IDT77252 is not set # CONFIG_ATM_AMBASSADOR is not set # CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set CONFIG_ATM_FORE200E_MAYBE=m CONFIG_ATM_FORE200E_PCA=y CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y @@ -835,7 +833,6 @@ CONFIG_ROSE=m # CONFIG_BAYCOM_SER_FDX is not set # CONFIG_BAYCOM_SER_HDX is not set # CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set # CONFIG_YAM is not set # @@ -1037,7 +1034,6 @@ CONFIG_I2C_I801=m CONFIG_I2C_I810=m CONFIG_I2C_NFORCE2=m CONFIG_I2C_PHILIPSPAR=m -CONFIG_I2C_PIIX4=m CONFIG_I2C_PROSAVAGE=m CONFIG_I2C_SAVAGE4=m CONFIG_SCx200_ACB=m @@ -1148,6 +1144,7 @@ CONFIG_UFS_FS_WRITE=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y CONFIG_NFS_V4=y +CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y CONFIG_NFSD_V4=y @@ -1273,7 +1270,7 @@ CONFIG_DVB_CORE=m # Supported Frontend Modules # CONFIG_DVB_STV0299=m -CONFIG_DVB_ALPS_BSRV2=m +CONFIG_DVB_SP887X=m CONFIG_DVB_ALPS_TDLB7=m CONFIG_DVB_ALPS_TDMB7=m CONFIG_DVB_ATMEL_AT76C651=m @@ -1282,6 +1279,7 @@ CONFIG_DVB_GRUNDIG_29504_491=m CONFIG_DVB_GRUNDIG_29504_401=m CONFIG_DVB_MT312=m CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m # # Supported SAA7146 based PCI Adapters @@ -1302,6 +1300,7 @@ CONFIG_DVB_BUDGET_PATCH=m # CONFIG_DVB_B2C2_SKYSTAR=m CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m CONFIG_VIDEO_VIDEOBUF=m CONFIG_VIDEO_TUNER=m CONFIG_VIDEO_BUF=m diff -prauN linux-2.6.0-test7/arch/sparc64/kernel/smp.c wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/smp.c --- linux-2.6.0-test7/arch/sparc64/kernel/smp.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/smp.c 2003-10-14 03:01:39.000000000 -0700 @@ -675,9 +675,9 @@ static __inline__ void __local_flush_dca #if (L1DCACHE_SIZE > PAGE_SIZE) __flush_dcache_page(page->virtual, ((tlb_type == spitfire) && - page->mapping != NULL)); + page_mapping(page) != NULL)); #else - if (page->mapping != NULL && + if (page_mapping(page) != NULL && tlb_type == spitfire) __flush_icache_page(__pa(page->virtual)); #endif @@ -698,7 +698,7 @@ void smp_flush_dcache_page_impl(struct p if (tlb_type == spitfire) { data0 = ((u64)&xcall_flush_dcache_page_spitfire); - if (page->mapping != NULL) + if (page_mapping(page) != NULL) data0 |= ((u64)1 << 32); spitfire_xcall_deliver(data0, __pa(page->virtual), @@ -720,9 +720,10 @@ void smp_flush_dcache_page_impl(struct p void flush_dcache_page_all(struct mm_struct *mm, struct page *page) { cpumask_t mask = cpu_online_map; - cpu_clear(smp_processor_id(), mask); u64 data0; + cpu_clear(smp_processor_id(), mask); + #ifdef CONFIG_DEBUG_DCFLUSH atomic_inc(&dcpage_flushes); #endif @@ -730,7 +731,7 @@ void flush_dcache_page_all(struct mm_str goto flush_self; if (tlb_type == spitfire) { data0 = ((u64)&xcall_flush_dcache_page_spitfire); - if (page->mapping != NULL) + if (page_mapping(page) != NULL) data0 |= ((u64)1 << 32); spitfire_xcall_deliver(data0, __pa(page->virtual), diff -prauN linux-2.6.0-test7/arch/sparc64/kernel/sparc64_ksyms.c wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/sparc64_ksyms.c --- linux-2.6.0-test7/arch/sparc64/kernel/sparc64_ksyms.c 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/sparc64_ksyms.c 2003-10-14 02:49:46.000000000 -0700 @@ -68,7 +68,6 @@ extern void die_if_kernel(char *str, str extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); void _sigpause_common (unsigned int set, struct pt_regs *); extern void *__bzero(void *, size_t); -extern void *__bzero_noasi(void *, size_t); extern void *__memscan_zero(void *, size_t); extern void *__memscan_generic(void *, int, size_t); extern int __memcmp(const void *, const void *, __kernel_size_t); diff -prauN linux-2.6.0-test7/arch/sparc64/kernel/unaligned.c wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/unaligned.c --- linux-2.6.0-test7/arch/sparc64/kernel/unaligned.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/kernel/unaligned.c 2003-10-14 02:49:46.000000000 -0700 @@ -73,6 +73,14 @@ static inline int decode_access_size(uns else { printk("Impossible unaligned trap. insn=%08x\n", insn); die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); + + /* GCC should never warn that control reaches the end + * of this function without returning a value because + * die_if_kernel() is marked with attribute 'noreturn'. + * Alas, some versions do... + */ + + return 0; } } diff -prauN linux-2.6.0-test7/arch/sparc64/mm/generic.c wli-2.6.0-test7-bk5-36/arch/sparc64/mm/generic.c --- linux-2.6.0-test7/arch/sparc64/mm/generic.c 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/mm/generic.c 2003-10-14 02:53:51.000000000 -0700 @@ -85,7 +85,7 @@ static inline void io_remap_pte_range(pt } while (address < end); } -static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigned long size, +static inline int io_remap_pmd_range(pgd_t *pgd, pmd_t * pmd, unsigned long address, unsigned long size, unsigned long offset, pgprot_t prot, int space) { unsigned long end; @@ -96,7 +96,7 @@ static inline int io_remap_pmd_range(pmd end = PGDIR_SIZE; offset -= address; do { - pte_t * pte = pte_alloc_map(current->mm, pmd, address); + pte_t * pte = pte_alloc_map(current->mm, pgd, &pmd, address); if (!pte) return -ENOMEM; io_remap_pte_range(pte, address, end - address, address + offset, prot, space); @@ -122,11 +122,11 @@ int io_remap_page_range(struct vm_area_s spin_lock(&mm->page_table_lock); while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); + pmd_t *pmd = pmd_alloc_map(current->mm, dir, from); error = -ENOMEM; if (!pmd) break; - error = io_remap_pmd_range(pmd, from, end - from, offset + from, prot, space); + error = io_remap_pmd_range(pgd, pmd, from, end - from, offset + from, prot, space); if (error) break; from = (from + PGDIR_SIZE) & PGDIR_MASK; diff -prauN linux-2.6.0-test7/arch/sparc64/mm/hugetlbpage.c wli-2.6.0-test7-bk5-36/arch/sparc64/mm/hugetlbpage.c --- linux-2.6.0-test7/arch/sparc64/mm/hugetlbpage.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/mm/hugetlbpage.c 2003-10-14 03:01:39.000000000 -0700 @@ -74,8 +74,8 @@ static struct page *alloc_hugetlb_page(v static void free_hugetlb_page(struct page *page) { spin_lock(&htlbpage_lock); - if ((page->mapping != NULL) && (page_count(page) == 2)) { - struct inode *inode = page->mapping->host; + if ((page_mapping(page) != NULL) && (page_count(page) == 2)) { + struct inode *inode = page_mapping(page)->host; int i; ClearPageDirty(page); @@ -107,9 +107,11 @@ static pte_t *huge_pte_alloc_map(struct pgd = pgd_offset(mm, addr); if (pgd) { - pmd = pmd_alloc(mm, pgd, addr); - if (pmd) - pte = pte_alloc_map(mm, pmd, addr); + pmd = pmd_alloc_map(mm, pgd, addr); + if (pmd) { + pte = pte_alloc_map(mm, pgd, &pmd, addr); + pmd_unmap(pmd); + } } return pte; } @@ -122,9 +124,11 @@ static pte_t *huge_pte_offset_map(struct pgd = pgd_offset(mm, addr); if (pgd) { - pmd = pmd_offset(pgd, addr); - if (pmd) + pmd = pmd_offset_map(pgd, addr); + if (pmd) { pte = pte_offset_map(pmd, addr); + pmd_unmap(pmd); + } } return pte; } diff -prauN linux-2.6.0-test7/arch/sparc64/mm/init.c wli-2.6.0-test7-bk5-36/arch/sparc64/mm/init.c --- linux-2.6.0-test7/arch/sparc64/mm/init.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/mm/init.c 2003-10-14 03:01:39.000000000 -0700 @@ -128,9 +128,9 @@ __inline__ void flush_dcache_page_impl(s #if (L1DCACHE_SIZE > PAGE_SIZE) __flush_dcache_page(page->virtual, ((tlb_type == spitfire) && - page->mapping != NULL)); + page_mapping(page) != NULL)); #else - if (page->mapping != NULL && + if (page_mapping(page) != NULL && tlb_type == spitfire) __flush_icache_page(__pa(page->virtual)); #endif @@ -192,7 +192,7 @@ void update_mmu_cache(struct vm_area_str pfn = pte_pfn(pte); if (pfn_valid(pfn) && - (page = pfn_to_page(pfn), page->mapping) && + (page = pfn_to_page(pfn), page_mapping(page)) && ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL)); @@ -216,9 +216,9 @@ void flush_dcache_page(struct page *page int dirty = test_bit(PG_dcache_dirty, &page->flags); int dirty_cpu = dcache_dirty_cpu(page); - if (page->mapping && - list_empty(&page->mapping->i_mmap) && - list_empty(&page->mapping->i_mmap_shared)) { + if (page_mapping(page) && + list_empty(&page_mapping(page)->i_mmap) && + list_empty(&page_mapping(page)->i_mmap_shared)) { if (dirty) { if (dirty_cpu == smp_processor_id()) return; @@ -226,7 +226,7 @@ void flush_dcache_page(struct page *page } set_dcache_dirty(page); } else { - /* We could delay the flush for the !page->mapping + /* We could delay the flush for the !page_mapping(page) * case too. But that case is for exec env/arg * pages and those are %99 certainly going to get * faulted into the tlb (and thus flushed) anyways. @@ -268,7 +268,7 @@ static inline void flush_cache_pte_range if (!pfn_valid(pfn)) continue; page = pfn_to_page(pfn); - if (PageReserved(page) || !page->mapping) + if (PageReserved(page) || !page_mapping(page)) continue; pgaddr = (unsigned long) page_address(page); uaddr = address + offset; diff -prauN linux-2.6.0-test7/arch/sparc64/mm/ultra.S wli-2.6.0-test7-bk5-36/arch/sparc64/mm/ultra.S --- linux-2.6.0-test7/arch/sparc64/mm/ultra.S 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/mm/ultra.S 2003-10-14 03:01:39.000000000 -0700 @@ -615,7 +615,7 @@ xcall_flush_dcache_page_cheetah: /* %g1 .globl xcall_flush_dcache_page_spitfire xcall_flush_dcache_page_spitfire: /* %g1 == physical page address %g7 == kernel page virtual address - %g5 == (page->mapping != NULL) */ + %g5 == (page_mapping(page) != NULL) */ #if (L1DCACHE_SIZE > PAGE_SIZE) srlx %g1, (13 - 2), %g1 ! Form tag comparitor sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K diff -prauN linux-2.6.0-test7/arch/sparc64/solaris/misc.c wli-2.6.0-test7-bk5-36/arch/sparc64/solaris/misc.c --- linux-2.6.0-test7/arch/sparc64/solaris/misc.c 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/sparc64/solaris/misc.c 2003-10-14 02:49:46.000000000 -0700 @@ -402,7 +402,7 @@ asmlinkage int solaris_procids(int cmd, Solaris setpgrp and setsid? */ ret = sys_setpgid(0, 0); if (ret) return ret; - current->signal->tty = NULL; + current->tty = NULL; return process_group(current); } case 2: /* getsid */ diff -prauN linux-2.6.0-test7/arch/x86_64/ia32/ia32_binfmt.c wli-2.6.0-test7-bk5-36/arch/x86_64/ia32/ia32_binfmt.c --- linux-2.6.0-test7/arch/x86_64/ia32/ia32_binfmt.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/ia32/ia32_binfmt.c 2003-10-14 02:58:33.000000000 -0700 @@ -371,7 +371,8 @@ int setup_arg_pages(struct linux_binprm struct page *page = bprm->page[i]; if (page) { bprm->page[i] = NULL; - put_dirty_page(current,page,stack_base,PAGE_COPY_EXEC); + put_dirty_page(current, mpnt, page, + stack_base, PAGE_COPY_EXEC); } stack_base += PAGE_SIZE; } diff -prauN linux-2.6.0-test7/arch/x86_64/ia32/syscall32.c wli-2.6.0-test7-bk5-36/arch/x86_64/ia32/syscall32.c --- linux-2.6.0-test7/arch/x86_64/ia32/syscall32.c 2003-10-08 12:24:16.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/ia32/syscall32.c 2003-10-14 02:53:51.000000000 -0700 @@ -29,12 +29,15 @@ char *syscall32_page; and let it be handled by generic VM */ int map_syscall32(struct mm_struct *mm, unsigned long address) { + pgd_t *pgd; + pmd_t *pmd; pte_t *pte; int err = 0; down_read(&mm->mmap_sem); spin_lock(&mm->page_table_lock); - pmd_t *pmd = pmd_alloc(mm, pgd_offset(mm, address), address); - if (pmd && (pte = pte_alloc_map(mm, pmd, address)) != NULL) { + pgd = pgd_offset(mm, address); + pmd = pmd_alloc_map(mm, pgd, address); + if (pmd && (pte = pte_alloc_map(mm, pgd, &pmd, address)) != NULL) { if (pte_none(*pte)) { set_pte(pte, mk_pte(virt_to_page(syscall32_page), diff -prauN linux-2.6.0-test7/arch/x86_64/kernel/acpi/boot.c wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/acpi/boot.c --- linux-2.6.0-test7/arch/x86_64/kernel/acpi/boot.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/acpi/boot.c 2003-10-14 02:49:46.000000000 -0700 @@ -46,10 +46,8 @@ #include #include -extern int acpi_disabled; int acpi_lapic = 0; int acpi_ioapic = 0; -extern int disable_apic; #define PREFIX "ACPI: " @@ -316,7 +314,7 @@ acpi_boot_init (void) { int result = 0; - if (acpi_disabled) + if (acpi_disabled && !acpi_ht) return 1; /* @@ -339,9 +337,10 @@ acpi_boot_init (void) return result; } - extern int disable_apic; - if (disable_apic) + if (disable_apic) { + printk(KERN_INFO PREFIX "Skipping MADT probe because local APIC is disabled\n"); return 0; + } #ifdef CONFIG_X86_LOCAL_APIC @@ -423,7 +422,7 @@ acpi_boot_init (void) /* * if "noapic" boot option, don't look for IO-APICs */ - if (disable_apic) { + if (skip_ioapic_setup) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " "due to 'noapic' option.\n"); return 1; diff -prauN linux-2.6.0-test7/arch/x86_64/kernel/apic.c wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/apic.c --- linux-2.6.0-test7/arch/x86_64/kernel/apic.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/apic.c 2003-10-14 02:49:46.000000000 -0700 @@ -1023,8 +1023,11 @@ static __init int setup_noapictimer(char return 0; } +/* dummy parsing: see setup.c */ + __setup("disableapic", setup_disableapic); __setup("nolapic", setup_nolapic); /* same as disableapic, for compatibility */ + __setup("noapictimer", setup_noapictimer); /* no "lapic" flag - we only use the lapic when the BIOS tells us so. */ diff -prauN linux-2.6.0-test7/arch/x86_64/kernel/cpufreq/Makefile wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/cpufreq/Makefile --- linux-2.6.0-test7/arch/x86_64/kernel/cpufreq/Makefile 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/cpufreq/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -4,9 +4,4 @@ obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o -$(obj)/powernow-k8.c: $(obj)/powernow-k8.h - @ln -sf ../../../i386/kernel/cpu/cpufreq/powernow-k8.c $(obj)/powernow-k8.c -$(obj)/powernow-k8.h: - @ln -sf ../../../i386/kernel/cpu/cpufreq/powernow-k8.h $(obj)/powernow-k8.h - -clean-files += powernow-k8.c powernow-k8.h +powernow-k8-objs := ../../../i386/kernel/cpu/cpufreq/powernow-k8.o diff -prauN linux-2.6.0-test7/arch/x86_64/kernel/io_apic.c wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/io_apic.c --- linux-2.6.0-test7/arch/x86_64/kernel/io_apic.c 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/io_apic.c 2003-10-14 02:49:46.000000000 -0700 @@ -176,14 +176,79 @@ static void clear_IO_APIC (void) int pirq_entries [MAX_PIRQS]; int pirqs_enabled; int skip_ioapic_setup; +int ioapic_force; -static int __init ioapic_setup(char *str) +/* dummy parsing: see setup.c */ + +static int __init disable_ioapic_setup(char *str) { skip_ioapic_setup = 1; return 1; } -__setup("noapic", ioapic_setup); +static int __init enable_ioapic_setup(char *str) +{ + ioapic_force = 1; + skip_ioapic_setup = 0; + return 1; +} + +__setup("noapic", disable_ioapic_setup); +__setup("apic", enable_ioapic_setup); + +#ifndef CONFIG_SMP +#include +#include +#include + +/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC + off. Check for an Nvidia or VIA PCI bridge and turn it off. + Use pci direct infrastructure because this runs before the PCI subsystem. + + Can be overwritten with "apic" */ +void __init check_ioapic(void) +{ + int num,slot,func; + if (ioapic_force) + return; + + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class; + u32 vendor; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) + continue; + + vendor = read_pci_config(num, slot, func, + PCI_VENDOR_ID); + vendor &= 0xffff; + switch (vendor) { + case PCI_VENDOR_ID_NVIDIA: + case PCI_VENDOR_ID_VIA: + printk(KERN_INFO + "PCI bridge %02x:%02x from %x found. Setting \"noapic\". Overwrite with \"apic\"\n", + num,slot,vendor); + skip_ioapic_setup = 1; + return; + } + + /* No multi-function device? */ + u8 type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } +} +#endif static int __init ioapic_pirq_setup(char *str) { diff -prauN linux-2.6.0-test7/arch/x86_64/kernel/setup.c wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/setup.c --- linux-2.6.0-test7/arch/x86_64/kernel/setup.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/kernel/setup.c 2003-10-14 02:49:46.000000000 -0700 @@ -65,6 +65,7 @@ unsigned long mmu_cr4_features; EXPORT_SYMBOL_GPL(mmu_cr4_features); int acpi_disabled = 0; +int acpi_ht = 0; /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0x10000000; @@ -204,9 +205,24 @@ static __init void parse_cmdline_early ( acpi_disabled = 0; } - if (!memcmp(from, "disableapic", 11)) + /* acpi=ht just means: do ACPI MADT parsing + at bootup, but don't enable the full ACPI interpreter */ + if (!memcmp(from, "acpi=ht", 7)) { + acpi_ht = 1; + } + + if (!memcmp(from, "nolapic", 7) || + !memcmp(from, "disableapic", 11)) disable_apic = 1; + if (!memcmp(from, "noapic", 6)) + skip_ioapic_setup = 1; + + if (!memcmp(from, "apic", 6)) { + skip_ioapic_setup = 0; + ioapic_force = 1; + } + if (!memcmp(from, "mem=", 4)) parse_memopt(from+4, &from); @@ -417,6 +433,13 @@ void __init setup_arch(char **cmdline_p) #endif paging_init(); + +#ifndef CONFIG_SMP + /* Temporary hack: disable the IO-APIC for UP Nvidia and + This is until we sort out the ACPI problems. */ + if (!acpi_disabled) + check_ioapic(); +#endif #ifdef CONFIG_ACPI_BOOT /* * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). diff -prauN linux-2.6.0-test7/arch/x86_64/mm/Makefile wli-2.6.0-test7-bk5-36/arch/x86_64/mm/Makefile --- linux-2.6.0-test7/arch/x86_64/mm/Makefile 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/mm/Makefile 2003-10-14 02:49:46.000000000 -0700 @@ -7,7 +7,4 @@ obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpag obj-$(CONFIG_DISCONTIGMEM) += numa.o obj-$(CONFIG_K8_NUMA) += k8topology.o -$(obj)/hugetlbpage.c: - @ln -sf ../../i386/mm/hugetlbpage.c $(obj)/hugetlbpage.c - -clean-files += hugetlbpage.c +hugetlbpage-y = ../../i386/mm/hugetlbpage.o diff -prauN linux-2.6.0-test7/arch/x86_64/mm/ioremap.c wli-2.6.0-test7-bk5-36/arch/x86_64/mm/ioremap.c --- linux-2.6.0-test7/arch/x86_64/mm/ioremap.c 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/arch/x86_64/mm/ioremap.c 2003-10-14 02:53:51.000000000 -0700 @@ -82,7 +82,7 @@ static int remap_area_pages(unsigned lon spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); + pmd = pmd_alloc_kernel(&init_mm, dir, address); error = -ENOMEM; if (!pmd) break; diff -prauN linux-2.6.0-test7/drivers/acpi/asus_acpi.c wli-2.6.0-test7-bk5-36/drivers/acpi/asus_acpi.c --- linux-2.6.0-test7/drivers/acpi/asus_acpi.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/asus_acpi.c 2003-10-14 02:49:46.000000000 -0700 @@ -33,7 +33,6 @@ */ #include - #include #include #include diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exconfig.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exconfig.c --- linux-2.6.0-test7/drivers/acpi/executer/exconfig.c 2003-10-08 12:24:15.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exconfig.c 2003-10-14 02:49:46.000000000 -0700 @@ -92,6 +92,9 @@ acpi_ex_add_table ( /* Install the new table into the local data structures */ + ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc)); + + table_info.type = 5; table_info.pointer = table; table_info.length = (acpi_size) table->length; table_info.allocation = ACPI_MEM_ALLOCATED; @@ -178,7 +181,7 @@ acpi_ex_load_table_op ( return_ACPI_STATUS (status); } - /* Not found, return an Integer=0 and AE_OK */ + /* Table not found, return an Integer=0 and AE_OK */ ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); if (!ddb_handle) { @@ -248,9 +251,11 @@ acpi_ex_load_table_op ( walk_state); if (ACPI_FAILURE (status)) { (void) acpi_ex_unload_table (ddb_handle); + return_ACPI_STATUS (status); } } + *return_desc = ddb_handle; return_ACPI_STATUS (status); } @@ -417,7 +422,7 @@ acpi_status acpi_ex_unload_table ( union acpi_operand_object *ddb_handle) { - acpi_status status = AE_NOT_IMPLEMENTED; + acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; struct acpi_table_desc *table_info; diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exfield.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exfield.c --- linux-2.6.0-test7/drivers/acpi/executer/exfield.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exfield.c 2003-10-14 02:49:46.000000000 -0700 @@ -160,10 +160,10 @@ acpi_ex_read_data_from_field ( } ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Obj=%p Type=%X Buf=%p Len=%X\n", + "field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n", obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length)); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "field_write: bit_len=%X bit_off=%X byte_off=%X\n", + "field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n", obj_desc->common_field.bit_length, obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.base_byte_offset)); @@ -335,10 +335,13 @@ acpi_ex_write_data_to_field ( } ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Obj=%p Type=%X Buf=%p Len=%X\n", - obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length)); + "field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n", + source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)), + ACPI_GET_OBJECT_TYPE (source_desc), buffer, length)); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "field_read: bit_len=%X bit_off=%X byte_off=%X\n", + "field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n", + obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)), + ACPI_GET_OBJECT_TYPE (obj_desc), obj_desc->common_field.bit_length, obj_desc->common_field.start_field_bit_offset, obj_desc->common_field.base_byte_offset)); diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exfldio.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exfldio.c --- linux-2.6.0-test7/drivers/acpi/executer/exfldio.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exfldio.c 2003-10-14 02:49:46.000000000 -0700 @@ -64,7 +64,8 @@ * RETURN: Status * * DESCRIPTION: Common processing for acpi_ex_extract_from_field and - * acpi_ex_insert_into_field. Initialize the + * acpi_ex_insert_into_field. Initialize the Region if necessary and + * validate the request. * ******************************************************************************/ @@ -96,7 +97,7 @@ acpi_ex_setup_region ( * If the Region Address and Length have not been previously evaluated, * evaluate them now and save the results. */ - if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { + if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) { status = acpi_ds_get_region_arguments (rgn_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -109,6 +110,18 @@ acpi_ex_setup_region ( return_ACPI_STATUS (AE_OK); } +#ifdef ACPI_UNDER_DEVELOPMENT + /* + * If the Field access is any_acc, we can now compute the optimal + * access (because we know know the length of the parent region) + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } +#endif + /* * Validate the request. The entire request from the byte offset for a * length of one field datum (access width) must fit within the region. @@ -242,7 +255,7 @@ acpi_ex_access_region ( } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD, - " Region[%s-%X] Access %X Base:Off %X:%X at %8.8X%8.8X\n", + " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name (rgn_desc->region.space_id), rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, @@ -365,10 +378,10 @@ acpi_ex_field_datum_io ( /* * The four types of fields are: * - * buffer_fields - Read/write from/to a Buffer - * region_fields - Read/write from/to a Operation Region. - * bank_fields - Write to a Bank Register, then read/write from/to an op_region - * index_fields - Write to an Index Register, then read/write from/to a Data Register + * buffer_field - Read/write from/to a Buffer + * region_field - Read/write from/to a Operation Region. + * bank_field - Write to a Bank Register, then read/write from/to an op_region + * index_field - Write to an Index Register, then read/write from/to a Data Register */ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_BUFFER_FIELD: @@ -458,24 +471,34 @@ acpi_ex_field_datum_io ( /* Write the index value to the index_register (itself a region_field) */ + field_datum_byte_offset += obj_desc->index_field.value; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Write to Index Register: Value %8.8X\n", + field_datum_byte_offset)); + status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj, - &obj_desc->index_field.value, - sizeof (obj_desc->index_field.value)); + &field_datum_byte_offset, + sizeof (field_datum_byte_offset)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "I/O to Data Register: value_ptr %p\n", + value)); + if (read_write == ACPI_READ) { /* Read the datum from the data_register */ status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj, - value, obj_desc->common_field.access_byte_width); + value, sizeof (acpi_integer)); } else { - /* Write the datum to the Data register */ + /* Write the datum to the data_register */ status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj, - value, obj_desc->common_field.access_byte_width); + value, sizeof (acpi_integer)); } break; @@ -490,12 +513,14 @@ acpi_ex_field_datum_io ( if (ACPI_SUCCESS (status)) { if (read_write == ACPI_READ) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read=%8.8X%8.8X\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + obj_desc->common_field.access_byte_width)); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written=%8.8X%8.8X\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + obj_desc->common_field.access_byte_width)); } } @@ -554,6 +579,10 @@ acpi_ex_write_with_update_rule ( */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, ¤t_value, ACPI_READ); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + merged_value |= (current_value & ~mask); } break; @@ -573,6 +602,7 @@ acpi_ex_write_with_update_rule ( break; default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "write_with_update_rule: Unknown update_rule setting: %X\n", (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK))); @@ -580,18 +610,19 @@ acpi_ex_write_with_update_rule ( } } - /* Write the merged value */ - - status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, - &merged_value, ACPI_WRITE); - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Mask %8.8X%8.8X datum_offset %X Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", + "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", ACPI_HIDWORD (mask), ACPI_LODWORD (mask), field_datum_byte_offset, + obj_desc->common_field.access_byte_width, ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value), ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value))); + /* Write the merged value */ + + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &merged_value, ACPI_WRITE); + return_ACPI_STATUS (status); } @@ -625,7 +656,7 @@ acpi_ex_get_buffer_datum ( u32 index; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_U32 ("ex_get_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ @@ -659,6 +690,8 @@ acpi_ex_get_buffer_datum ( /* Should not get here */ break; } + + return_VOID; } @@ -690,7 +723,8 @@ acpi_ex_set_buffer_datum ( { u32 index; - ACPI_FUNCTION_ENTRY (); + + ACPI_FUNCTION_TRACE_U32 ("ex_set_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ @@ -724,6 +758,8 @@ acpi_ex_set_buffer_datum ( /* Should not get here */ break; } + + return_VOID; } @@ -777,7 +813,7 @@ acpi_ex_extract_from_field ( obj_desc->common_field.access_byte_width); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "byte_len=%X, datum_len=%X, byte_gran=%X\n", + "byte_len %X, datum_len %X, byte_gran %X\n", byte_field_length, datum_count,obj_desc->common_field.access_byte_width)); /* @@ -942,20 +978,27 @@ acpi_ex_insert_into_field ( * larger than the field, this typically happens when an integer is * written to a field that is actually smaller than an integer. */ - byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.bit_length); if (buffer_length < byte_field_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Buffer length %X too small for field %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Buffer length %X too small for field %X\n", buffer_length, byte_field_length)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.start_field_bit_offset + + obj_desc->common_field.bit_length); + /* Convert byte count to datum count, round up if necessary */ - datum_count = ACPI_ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + datum_count = ACPI_ROUND_UP_TO (byte_field_length, + obj_desc->common_field.access_byte_width); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "byte_len=%X, datum_len=%X, byte_gran=%X\n", + "Bytes %X, Datums %X, byte_gran %X\n", byte_field_length, datum_count, obj_desc->common_field.access_byte_width)); /* @@ -1006,6 +1049,10 @@ acpi_ex_insert_into_field ( return_ACPI_STATUS (status); } + /* We just wrote the first datum */ + + datum_offset++; + /* If the entire field fits within one datum, we are done. */ if ((datum_count == 1) && @@ -1025,7 +1072,6 @@ acpi_ex_insert_into_field ( * applied in Part3 below. */ while (datum_offset < datum_count) { - datum_offset++; field_datum_byte_offset += obj_desc->common_field.access_byte_width; /* @@ -1057,33 +1103,34 @@ acpi_ex_insert_into_field ( * a datum boundary. Update Rule must be applied to the bits outside * the field. */ - if (datum_offset == datum_count) { + datum_offset++; + if ((datum_offset == datum_count) && + (obj_desc->common_field.end_field_valid_bits)) { /* * If there are dangling non-aligned bits, perform one more merged write * Else - field is aligned at the end, no need for any more writes */ - if (obj_desc->common_field.end_field_valid_bits) { - /* - * Part3: - * This is the last datum and the field does not end on a datum boundary. - * Build the partial datum and write with the update rule. - * - * Mask off the unused bits above (after) the end-of-field - */ - mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); - merged_datum &= mask; - /* Write the last datum with the update rule */ + /* + * Part3: + * This is the last datum and the field does not end on a datum boundary. + * Build the partial datum and write with the update rule. + * + * Mask off the unused bits above (after) the end-of-field + */ + mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + merged_datum &= mask; + + /* Write the last datum with the update rule */ - status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, - field_datum_byte_offset); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, + field_datum_byte_offset); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } } else { - /* Normal case -- write the completed datum */ + /* Normal (aligned) case -- write the completed datum */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, &merged_datum, ACPI_WRITE); diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exoparg1.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exoparg1.c --- linux-2.6.0-test7/drivers/acpi/executer/exoparg1.c 2003-10-08 12:24:44.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exoparg1.c 2003-10-14 02:49:46.000000000 -0700 @@ -524,7 +524,7 @@ acpi_ex_opcode_1A_0T_1R ( acpi_integer value; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); /* Examine the AML opcode */ diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exprep.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exprep.c --- linux-2.6.0-test7/drivers/acpi/executer/exprep.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exprep.c 2003-10-14 02:49:46.000000000 -0700 @@ -53,6 +53,133 @@ ACPI_MODULE_NAME ("exprep") +#ifdef ACPI_UNDER_DEVELOPMENT +/******************************************************************************* + * + * FUNCTION: acpi_ex_generate_access + * + * PARAMETERS: field_bit_offset - Start of field within parent region/buffer + * field_bit_length - Length of field in bits + * region_length - Length of parent in bytes + * + * RETURN: Field granularity (8, 16, 32 or 64) and + * byte_alignment (1, 2, 3, or 4) + * + * DESCRIPTION: Generate an optimal access width for fields defined with the + * any_acc keyword. + * + * NOTE: Need to have the region_length in order to check for boundary + * conditions (end-of-region). However, the region_length is a deferred + * operation. Therefore, to complete this implementation, the generation + * of this access width must be deferred until the region length has + * been evaluated. + * + ******************************************************************************/ + +static u32 +acpi_ex_generate_access ( + u32 field_bit_offset, + u32 field_bit_length, + u32 region_length) +{ + u32 field_byte_length; + u32 field_byte_offset; + u32 field_byte_end_offset; + u32 access_byte_width; + u32 field_start_offset; + u32 field_end_offset; + u32 minimum_access_width = 0xFFFFFFFF; + u32 minimum_accesses = 0xFFFFFFFF; + u32 accesses; + + + ACPI_FUNCTION_TRACE ("ex_generate_access"); + + + /* Round Field start offset and length to "minimal" byte boundaries */ + + field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8)); + field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8)); + field_byte_length = field_byte_end_offset - field_byte_offset; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Bit length %d, Bit offset %d\n", + field_bit_length, field_bit_offset)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Byte Length %d, Byte Offset %d, End Offset %d\n", + field_byte_length, field_byte_offset, field_byte_end_offset)); + + /* + * Iterative search for the maximum access width that is both aligned + * and does not go beyond the end of the region + * + * Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes) + */ + for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) { + /* + * 1) Round end offset up to next access boundary and make sure that this + * does not go beyond the end of the parent region. + * 2) When the Access width is greater than the field_byte_length, we are done. + * (This does not optimize for the perfectly aligned case yet). + */ + if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) { + field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) / + access_byte_width; + field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset), + access_byte_width) / access_byte_width; + accesses = field_end_offset - field_start_offset; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "access_width %d end is within region\n", access_byte_width)); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field Start %d, Field End %d -- requires %d accesses\n", + field_start_offset, field_end_offset, accesses)); + + /* Single access is optimal */ + + if (accesses <= 1) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Entire field can be accessed with one operation of size %d\n", + access_byte_width)); + return_VALUE (access_byte_width); + } + + /* + * Fits in the region, but requires more than one read/write. + * try the next wider access on next iteration + */ + if (accesses < minimum_accesses) { + minimum_accesses = accesses; + minimum_access_width = access_byte_width; + } + } + else { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "access_width %d end is NOT within region\n", access_byte_width)); + if (access_byte_width == 1) { + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Field goes beyond end-of-region!\n")); + return_VALUE (0); /* Field does not fit in the region at all */ + } + + /* This width goes beyond the end-of-region, back off to previous access */ + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Backing off to previous optimal access width of %d\n", + minimum_access_width)); + return_VALUE (minimum_access_width); + } + } + + /* Could not read/write field with one operation, just use max access width */ + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Cannot access field in one operation, using width 8\n")); + return_VALUE (8); +} +#endif /* ACPI_UNDER_DEVELOPMENT */ + + /******************************************************************************* * * FUNCTION: acpi_ex_decode_field_access @@ -74,12 +201,11 @@ acpi_ex_decode_field_access ( u32 *return_byte_alignment) { u32 access; - u8 byte_alignment; - u8 bit_length; -/* u32 Length; */ + u32 byte_alignment; + u32 bit_length; - ACPI_FUNCTION_NAME ("ex_decode_field_access"); + ACPI_FUNCTION_TRACE ("ex_decode_field_access"); access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK); @@ -87,41 +213,15 @@ acpi_ex_decode_field_access ( switch (access) { case AML_FIELD_ACCESS_ANY: +#ifdef ACPI_UNDER_DEVELOPMENT + byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset, + obj_desc->common_field.bit_length, + 0xFFFFFFFF /* Temp until we pass region_length as param */); + bit_length = byte_alignment * 8; +#endif + byte_alignment = 1; bit_length = 8; - -#if 0 - /* - * TBD: optimize - * - * Any attempt to optimize the access size to the size of the field - * must take into consideration the length of the region and take - * care that an access to the field will not attempt to access - * beyond the end of the region. - */ - - /* Use the length to set the access type */ - - length = obj_desc->common_field.bit_length; - - if (length <= 8) { - bit_length = 8; - } - else if (length <= 16) { - bit_length = 16; - } - else if (length <= 32) { - bit_length = 32; - } - else if (length <= 64) { - bit_length = 64; - } - else { - /* Larger than Qword - just use byte-size chunks */ - - bit_length = 8; - } -#endif break; case AML_FIELD_ACCESS_BYTE: @@ -151,7 +251,7 @@ acpi_ex_decode_field_access ( ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown field access type %X\n", access)); - return (0); + return_VALUE (0); } if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) { @@ -164,7 +264,7 @@ acpi_ex_decode_field_access ( } *return_byte_alignment = byte_alignment; - return (bit_length); + return_VALUE (bit_length); } @@ -336,7 +436,7 @@ acpi_ex_prep_field_value ( type = acpi_ns_get_type (info->region_node); if (type != ACPI_TYPE_REGION) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Needed Region, found type %X %s\n", + "Needed Region, found type %X (%s)\n", type, acpi_ut_get_type_name (type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); @@ -372,7 +472,7 @@ acpi_ex_prep_field_value ( acpi_ut_add_reference (obj_desc->field.region_obj); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "region_field: Bitoff=%X Off=%X Gran=%X Region %p\n", + "region_field: bit_off %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset, obj_desc->field.access_byte_width, obj_desc->field.region_obj)); break; @@ -390,7 +490,7 @@ acpi_ex_prep_field_value ( acpi_ut_add_reference (obj_desc->bank_field.bank_obj); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Bank Field: bit_off=%X Off=%X Gran=%X Region %p bank_reg %p\n", + "Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n", obj_desc->bank_field.start_field_bit_offset, obj_desc->bank_field.base_byte_offset, obj_desc->field.access_byte_width, @@ -417,9 +517,10 @@ acpi_ex_prep_field_value ( acpi_ut_add_reference (obj_desc->index_field.index_obj); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "index_field: bitoff=%X off=%X gran=%X Index %p Data %p\n", + "index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", obj_desc->index_field.start_field_bit_offset, obj_desc->index_field.base_byte_offset, + obj_desc->index_field.value, obj_desc->field.access_byte_width, obj_desc->index_field.index_obj, obj_desc->index_field.data_obj)); @@ -437,7 +538,7 @@ acpi_ex_prep_field_value ( status = acpi_ns_attach_object (info->field_node, obj_desc, acpi_ns_get_type (info->field_node)); - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "set named_obj %p (%4.4s) val = %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n", info->field_node, info->field_node->name.ascii, obj_desc)); /* Remove local reference to the object */ diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exresnte.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresnte.c --- linux-2.6.0-test7/drivers/acpi/executer/exresnte.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresnte.c 2003-10-14 02:49:46.000000000 -0700 @@ -47,6 +47,8 @@ #include #include #include +#include +#include #define _COMPONENT ACPI_EXECUTER @@ -243,12 +245,26 @@ acpi_ex_resolve_node_to_value ( case ACPI_TYPE_LOCAL_REFERENCE: - /* No named references are allowed here */ + switch (source_desc->reference.opcode) { + case AML_LOAD_OP: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X\n", - source_desc->reference.opcode)); + /* This is a ddb_handle */ + /* Return an additional reference to the object */ - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + obj_desc = source_desc; + acpi_ut_add_reference (obj_desc); + break; + + default: + /* No named references are allowed here */ + + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n", + source_desc->reference.opcode, + acpi_ps_get_opcode_name (source_desc->reference.opcode))); + + return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + } + break; /* Default case is for unknown types */ diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exresolv.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresolv.c --- linux-2.6.0-test7/drivers/acpi/executer/exresolv.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresolv.c 2003-10-14 02:49:46.000000000 -0700 @@ -48,6 +48,7 @@ #include #include #include +#include #define _COMPONENT ACPI_EXECUTER @@ -248,6 +249,7 @@ acpi_ex_resolve_object_to_value ( case AML_REF_OF_OP: case AML_DEBUG_OP: + case AML_LOAD_OP: /* Just leave the object as-is */ @@ -256,8 +258,8 @@ acpi_ex_resolve_object_to_value ( default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X in %p\n", - opcode, stack_desc)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X (%s) in %p\n", + opcode, acpi_ps_get_opcode_name (opcode), stack_desc)); status = AE_AML_INTERNAL; break; } diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exresop.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresop.c --- linux-2.6.0-test7/drivers/acpi/executer/exresop.c 2003-10-08 12:24:43.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exresop.c 2003-10-14 02:49:46.000000000 -0700 @@ -224,6 +224,7 @@ acpi_ex_resolve_operands ( case AML_REF_OF_OP: case AML_ARG_OP: case AML_LOCAL_OP: + case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Reference Opcode: %s\n", op_info->name))); @@ -231,8 +232,9 @@ acpi_ex_resolve_operands ( default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Unknown Reference Opcode %X\n", - obj_desc->reference.opcode)); + "Unknown Reference Opcode %X [%s]\n", + obj_desc->reference.opcode, + (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name)); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } @@ -378,6 +380,13 @@ acpi_ex_resolve_operands ( type_needed = ACPI_TYPE_ANY; break; + case ARGI_DDBHANDLE: + + /* Need an operand of type ACPI_TYPE_DDB_HANDLE */ + + type_needed = ACPI_TYPE_LOCAL_REFERENCE; + break; + /* * The more complex cases allow multiple resolved object types diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exstoren.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exstoren.c --- linux-2.6.0-test7/drivers/acpi/executer/exstoren.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exstoren.c 2003-10-14 02:49:46.000000000 -0700 @@ -46,6 +46,7 @@ #include #include +#include #define _COMPONENT ACPI_EXECUTER @@ -114,9 +115,10 @@ acpi_ex_resolve_object ( /* * Must have a Integer, Buffer, or String */ - if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) && - (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) && - (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)) { + if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) && + (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) && + (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) && + !((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) { /* * Conversion successful but still not a valid type */ diff -prauN linux-2.6.0-test7/drivers/acpi/executer/exsystem.c wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exsystem.c --- linux-2.6.0-test7/drivers/acpi/executer/exsystem.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/executer/exsystem.c 2003-10-14 02:49:46.000000000 -0700 @@ -129,18 +129,13 @@ acpi_ex_system_do_stall ( ACPI_FUNCTION_ENTRY (); - if (how_long > 1000) /* 1 millisecond */ { - /* Since this thread will sleep, we must release the interpreter */ - - acpi_ex_exit_interpreter (); - - acpi_os_sleep (0, (how_long / 1000) + 1); - - /* And now we must get the interpreter again */ - - status = acpi_ex_enter_interpreter (); + if (how_long > 100) /* 100 microseconds */ { + /* + * Longer than 100 usec, use sleep instead + * (according to ACPI specification) + */ + status = acpi_ex_system_do_suspend ((how_long / 1000) + 1); } - else { acpi_os_stall (how_long); } diff -prauN linux-2.6.0-test7/drivers/acpi/hardware/hwacpi.c wli-2.6.0-test7-bk5-36/drivers/acpi/hardware/hwacpi.c --- linux-2.6.0-test7/drivers/acpi/hardware/hwacpi.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/hardware/hwacpi.c 2003-10-14 02:49:46.000000000 -0700 @@ -208,6 +208,15 @@ acpi_hw_get_mode (void) ACPI_FUNCTION_TRACE ("hw_get_mode"); + + /* + * ACPI 2.0 clarified that if SMI_CMD in FADT is zero, + * system does not support mode transition. + */ + if (!acpi_gbl_FADT->smi_cmd) { + return_VALUE (ACPI_SYS_MODE_ACPI); + } + status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK); if (ACPI_FAILURE (status)) { return_VALUE (ACPI_SYS_MODE_LEGACY); diff -prauN linux-2.6.0-test7/drivers/acpi/resources/rsaddr.c wli-2.6.0-test7-bk5-36/drivers/acpi/resources/rsaddr.c --- linux-2.6.0-test7/drivers/acpi/resources/rsaddr.c 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/resources/rsaddr.c 2003-10-14 02:49:46.000000000 -0700 @@ -94,6 +94,12 @@ acpi_rs_address16_resource ( buffer += 1; ACPI_MOVE_16_TO_16 (&temp16, buffer); + /* Validate minimum descriptor length */ + + if (temp16 < 13) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS16; @@ -199,8 +205,11 @@ acpi_rs_address16_resource ( * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 16) { + if (*bytes_consumed > (16 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -401,7 +410,7 @@ acpi_rs_address16_stream ( /* * Buffer needs to be set to the length of the sting + one for the - * terminating null + * terminating null */ buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1); } @@ -470,8 +479,14 @@ acpi_rs_address32_resource ( */ buffer += 1; ACPI_MOVE_16_TO_16 (&temp16, buffer); - *bytes_consumed = temp16 + 3; + /* Validate minimum descriptor length */ + + if (temp16 < 23) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + + *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS32; /* @@ -578,8 +593,11 @@ acpi_rs_address32_resource ( * This will leave us pointing to the Resource Source Index * If it is present, then save it off and calculate the * pointer to where the null terminated string goes: + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 26) { + if (*bytes_consumed > (26 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -616,8 +634,8 @@ acpi_rs_address32_resource ( /* * In order for the struct_size to fall on a 32-bit boundary, - * calculate the length of the string and expand the - * struct_size to the next 32-bit boundary. + * calculate the length of the string and expand the + * struct_size to the next 32-bit boundary. */ temp8 = (u8) (index + 1); struct_size += ACPI_ROUND_UP_to_32_bITS (temp8); @@ -848,6 +866,12 @@ acpi_rs_address64_resource ( buffer += 1; ACPI_MOVE_16_TO_16 (&temp16, buffer); + /* Validate minimum descriptor length */ + + if (temp16 < 43) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_ADDRESS64; @@ -958,8 +982,11 @@ acpi_rs_address64_resource ( * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ - if (*bytes_consumed > 46) { + if (*bytes_consumed > (46 + 1)) { /* Dereference the Index */ temp8 = *buffer; @@ -992,7 +1019,6 @@ acpi_rs_address64_resource ( * Add the terminating null */ *temp_ptr = 0x00; - output_struct->data.address64.resource_source.string_length = index + 1; /* @@ -1064,7 +1090,6 @@ acpi_rs_address64_stream ( /* * Set a pointer to the Length field - to be filled in later */ - length_field = ACPI_CAST_PTR (u16, buffer); buffer += 2; @@ -1161,7 +1186,7 @@ acpi_rs_address64_stream ( /* * Buffer needs to be set to the length of the sting + one for the - * terminating null + * terminating null */ buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1); } diff -prauN linux-2.6.0-test7/drivers/acpi/resources/rsirq.c wli-2.6.0-test7-bk5-36/drivers/acpi/resources/rsirq.c --- linux-2.6.0-test7/drivers/acpi/resources/rsirq.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/resources/rsirq.c 2003-10-14 02:49:46.000000000 -0700 @@ -319,6 +319,12 @@ acpi_rs_extended_irq_resource ( buffer += 1; ACPI_MOVE_16_TO_16 (&temp16, buffer); + /* Validate minimum descriptor length */ + + if (temp16 < 6) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + *bytes_consumed = temp16 + 3; output_struct->id = ACPI_RSTYPE_EXT_IRQ; @@ -357,6 +363,12 @@ acpi_rs_extended_irq_resource ( buffer += 1; temp8 = *buffer; + /* Must have at least one IRQ */ + + if (temp8 < 1) { + return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH); + } + output_struct->data.extended_irq.number_of_interrupts = temp8; /* @@ -388,9 +400,12 @@ acpi_rs_extended_irq_resource ( * pointer to where the null terminated string goes: * Each Interrupt takes 32-bits + the 5 bytes of the * stream that are default. + * + * Note: Some resource descriptors will have an additional null, so + * we add 1 to the length. */ if (*bytes_consumed > - ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + 5) { + ((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) { /* Dereference the Index */ temp8 = *buffer; diff -prauN linux-2.6.0-test7/drivers/acpi/sleep/main.c wli-2.6.0-test7-bk5-36/drivers/acpi/sleep/main.c --- linux-2.6.0-test7/drivers/acpi/sleep/main.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/sleep/main.c 2003-10-14 02:49:46.000000000 -0700 @@ -20,8 +20,8 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; static struct pm_ops acpi_pm_ops; -extern void do_suspend_lowlevel_s4bios(int); -extern void do_suspend_lowlevel(int); +extern void do_suspend_lowlevel_s4bios(void); +extern void do_suspend_lowlevel(void); static u32 acpi_suspend_states[] = { [PM_SUSPEND_ON] = ACPI_STATE_S0, @@ -95,14 +95,14 @@ static int acpi_pm_enter(u32 state) break; case PM_SUSPEND_MEM: - do_suspend_lowlevel(0); + do_suspend_lowlevel(); break; case PM_SUSPEND_DISK: if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM) status = acpi_enter_sleep_state(acpi_state); else - do_suspend_lowlevel_s4bios(0); + do_suspend_lowlevel_s4bios(); break; default: return -EINVAL; diff -prauN linux-2.6.0-test7/drivers/acpi/tables/tbconvrt.c wli-2.6.0-test7-bk5-36/drivers/acpi/tables/tbconvrt.c --- linux-2.6.0-test7/drivers/acpi/tables/tbconvrt.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/tables/tbconvrt.c 2003-10-14 02:49:46.000000000 -0700 @@ -131,7 +131,7 @@ acpi_tb_convert_to_xsdt ( /* Copy the header and set the length */ ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header)); - new_table->header.length = (u32) table_size; + new_table->length = (u32) table_size; /* Copy the table pointers */ @@ -430,17 +430,17 @@ acpi_tb_convert_table_fadt (void) * FADT length and version validation. The table must be at least as * long as the version 1.0 FADT */ - if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev1)) { - ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->header.length)); + if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) { + ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->length)); return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); } - if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { - if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev2)) { + if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { + if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) { /* Length is too short to be a V2.0 table */ ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n", - acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.revision)); + acpi_gbl_FADT->length, acpi_gbl_FADT->revision)); acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT); } @@ -460,7 +460,7 @@ acpi_tb_convert_table_fadt (void) * Global FADT pointer will point to the new common V2.0 FADT */ acpi_gbl_FADT = local_fadt; - acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR); + acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ @@ -477,8 +477,8 @@ acpi_tb_convert_table_fadt (void) ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", - acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length)); - ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length); + acpi_gbl_FADT->length, acpi_gbl_FADT->length)); + ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length); return_ACPI_STATUS (AE_OK); } diff -prauN linux-2.6.0-test7/drivers/acpi/tables/tbinstal.c wli-2.6.0-test7-bk5-36/drivers/acpi/tables/tbinstal.c --- linux-2.6.0-test7/drivers/acpi/tables/tbinstal.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/tables/tbinstal.c 2003-10-14 02:49:46.000000000 -0700 @@ -350,7 +350,7 @@ acpi_tb_init_table_descriptor ( void acpi_tb_delete_all_tables (void) { - acpi_table_type type; + acpi_table_type type; /* @@ -378,7 +378,7 @@ acpi_tb_delete_all_tables (void) void acpi_tb_delete_tables_by_type ( - acpi_table_type type) + acpi_table_type type) { struct acpi_table_desc *table_desc; u32 count; @@ -425,15 +425,16 @@ acpi_tb_delete_tables_by_type ( break; } - /* Free the table */ - /* Get the head of the list */ - + /* + * Free the table + * 1) Get the head of the list + */ table_desc = acpi_gbl_table_lists[type].next; count = acpi_gbl_table_lists[type].count; /* - * Walk the entire list, deleting both the allocated tables - * and the table descriptors + * 2) Walk the entire list, deleting both the allocated tables + * and the table descriptors */ for (i = 0; i < count; i++) { table_desc = acpi_tb_uninstall_table (table_desc); diff -prauN linux-2.6.0-test7/drivers/acpi/utilities/utalloc.c wli-2.6.0-test7-bk5-36/drivers/acpi/utilities/utalloc.c --- linux-2.6.0-test7/drivers/acpi/utilities/utalloc.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/utilities/utalloc.c 2003-10-14 02:49:46.000000000 -0700 @@ -795,7 +795,7 @@ acpi_ut_remove_allocation ( ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size); - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size %X\n", allocation->size)); + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size)); status = acpi_ut_release_mutex (ACPI_MTX_MEMORY); return_ACPI_STATUS (status); diff -prauN linux-2.6.0-test7/drivers/acpi/utilities/utglobal.c wli-2.6.0-test7-bk5-36/drivers/acpi/utilities/utglobal.c --- linux-2.6.0-test7/drivers/acpi/utilities/utglobal.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/acpi/utilities/utglobal.c 2003-10-14 02:49:46.000000000 -0700 @@ -307,8 +307,8 @@ struct acpi_table_support acpi /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ /* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE}, - /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE}, - /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}, + /* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE}, + /* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE}, /* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE}, /* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, /* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE}, diff -prauN linux-2.6.0-test7/drivers/atm/Kconfig wli-2.6.0-test7-bk5-36/drivers/atm/Kconfig --- linux-2.6.0-test7/drivers/atm/Kconfig 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/atm/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -166,7 +166,7 @@ config ATM_ZATM_DEBUG # fi config ATM_NICSTAR tristate "IDT 77201 (NICStAR) (ForeRunnerLE)" - depends on PCI && ATM + depends on PCI && ATM && !64BIT help The NICStAR chipset family is used in a large number of ATM NICs for 25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE @@ -282,7 +282,7 @@ config ATM_HORIZON_DEBUG config ATM_IA tristate "Interphase ATM PCI x575/x525/x531" - depends on PCI && ATM + depends on PCI && ATM && !64BIT ---help--- This is a driver for the Interphase (i)ChipSAR adapter cards which include a variety of variants in term of the size of the diff -prauN linux-2.6.0-test7/drivers/base/bus.c wli-2.6.0-test7-bk5-36/drivers/base/bus.c --- linux-2.6.0-test7/drivers/base/bus.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/base/bus.c 2003-10-14 02:49:46.000000000 -0700 @@ -459,10 +459,6 @@ int bus_add_driver(struct device_driver driver_attach(drv); up_write(&bus->subsys.rwsem); - if (error) { - kobject_unregister(&drv->kobj); - put_bus(bus); - } } return error; } diff -prauN linux-2.6.0-test7/drivers/base/core.c wli-2.6.0-test7-bk5-36/drivers/base/core.c --- linux-2.6.0-test7/drivers/base/core.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/base/core.c 2003-10-14 02:49:46.000000000 -0700 @@ -76,6 +76,8 @@ static struct sysfs_ops dev_sysfs_ops = static void device_release(struct kobject * kobj) { struct device * dev = to_dev(kobj); + struct completion * c = dev->complete; + if (dev->release) dev->release(dev); else { @@ -84,6 +86,8 @@ static void device_release(struct kobjec dev->bus_id); WARN_ON(1); } + if (c) + complete(c); } static struct kobj_type ktype_device = { @@ -349,6 +353,26 @@ void device_unregister(struct device * d put_device(dev); } + +/** + * device_unregister_wait - Unregister device and wait for it to be freed. + * @dev: Device to unregister. + * + * For the cases where the caller needs to wait for all references to + * be dropped from the device before continuing (e.g. modules with + * statically allocated devices), this function uses a completion struct + * to wait, along with a matching complete() in device_release() above. + */ + +void device_unregister_wait(struct device * dev) +{ + struct completion c; + init_completion(&c); + dev->complete = &c; + device_unregister(dev); + wait_for_completion(&c); +} + /** * device_for_each_child - device child iterator. * @dev: parent struct device. @@ -389,6 +413,7 @@ EXPORT_SYMBOL(device_register); EXPORT_SYMBOL(device_del); EXPORT_SYMBOL(device_unregister); +EXPORT_SYMBOL(device_unregister_wait); EXPORT_SYMBOL(get_device); EXPORT_SYMBOL(put_device); diff -prauN linux-2.6.0-test7/drivers/block/Kconfig wli-2.6.0-test7-bk5-36/drivers/block/Kconfig --- linux-2.6.0-test7/drivers/block/Kconfig 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/block/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -6,7 +6,7 @@ menu "Block devices" config BLK_DEV_FD tristate "Normal floppy disk support" - depends on ISA || M68 || SPARC64 + depends on !X86_PC9800 && !ARCH_S390 ---help--- If you want to use the floppy disk drive(s) of your PC under Linux, say Y. Information about this driver, especially important for IBM diff -prauN linux-2.6.0-test7/drivers/char/Kconfig wli-2.6.0-test7-bk5-36/drivers/char/Kconfig --- linux-2.6.0-test7/drivers/char/Kconfig 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -851,7 +851,7 @@ config APPLICOM config SONYPI tristate "Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)" - depends on EXPERIMENTAL && X86 && PCI + depends on EXPERIMENTAL && X86 && PCI && !64BIT ---help--- This driver enables access to the Sony Programmable I/O Control Device which can be found in many (all ?) Sony Vaio laptops. diff -prauN linux-2.6.0-test7/drivers/char/drm/drm_memory.h wli-2.6.0-test7-bk5-36/drivers/char/drm/drm_memory.h --- linux-2.6.0-test7/drivers/char/drm/drm_memory.h 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/drm/drm_memory.h 2003-10-14 02:53:51.000000000 -0700 @@ -125,7 +125,7 @@ static inline unsigned long drm_follow_page (void *vaddr) { pgd_t *pgd = pgd_offset_k((unsigned long) vaddr); - pmd_t *pmd = pmd_offset(pgd, (unsigned long) vaddr); + pmd_t *pmd = pmd_offset_kernel(pgd, (unsigned long)vaddr); pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr); return pte_pfn(*ptep) << PAGE_SHIFT; } diff -prauN linux-2.6.0-test7/drivers/char/ftape/lowlevel/ftape-proc.c wli-2.6.0-test7-bk5-36/drivers/char/ftape/lowlevel/ftape-proc.c --- linux-2.6.0-test7/drivers/char/ftape/lowlevel/ftape-proc.c 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/ftape/lowlevel/ftape-proc.c 2003-10-14 02:49:46.000000000 -0700 @@ -207,11 +207,9 @@ int __init ftape_proc_init(void) ftape_read_proc, NULL) != NULL; } -#ifdef MODULE void ftape_proc_destroy(void) { remove_proc_entry("ftape", &proc_root); } -#endif #endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) */ diff -prauN linux-2.6.0-test7/drivers/char/ipmi/Kconfig wli-2.6.0-test7-bk5-36/drivers/char/ipmi/Kconfig --- linux-2.6.0-test7/drivers/char/ipmi/Kconfig 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/ipmi/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -24,6 +24,18 @@ config IPMI_PANIC_EVENT generate an IPMI event describing the panic to each interface registered with the message handler. +config IPMI_PANIC_STRING + bool 'Generate OEM events containing the panic string' + depends on IPMI_PANIC_EVENT + help + When a panic occurs, this will cause the IPMI message handler to + generate IPMI OEM type f0 events holding the IPMB address of the + panic generator (byte 4 of the event), a sequence number for the + string (byte 5 of the event) and part of the string (the rest of the + event). Bytes 1, 2, and 3 are the normal usage for an OEM event. + You can fetch these events and use the sequence numbers to piece the + string together. + config IPMI_DEVICE_INTERFACE tristate 'Device interface for IPMI' depends on IPMI_HANDLER diff -prauN linux-2.6.0-test7/drivers/char/ipmi/ipmi_msghandler.c wli-2.6.0-test7-bk5-36/drivers/char/ipmi/ipmi_msghandler.c --- linux-2.6.0-test7/drivers/char/ipmi/ipmi_msghandler.c 2003-10-08 12:24:08.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/ipmi/ipmi_msghandler.c 2003-10-14 02:49:46.000000000 -0700 @@ -169,6 +169,19 @@ struct ipmi_smi /* My LUN. This should generally stay the SMS LUN, but just in case... */ unsigned char my_lun; + + /* The event receiver for my BMC, only really used at panic + shutdown as a place to store this. */ + unsigned char event_receiver; + unsigned char event_receiver_lun; + unsigned char local_sel_device; + unsigned char local_event_generator; + + /* A cheap hack, if this is non-null and a message to an + interface comes in with a NULL user, call this routine with + it. Note that the message will still be freed by the + caller. This only works on the system interface. */ + void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_smi_msg *msg); }; int @@ -1465,6 +1478,9 @@ static int handle_bmc_rsp(ipmi_smi_t } if (!found) { + /* Special handling for NULL users. */ + if (!recv_msg->user && intf->null_user_handler) + intf->null_user_handler(intf, msg); /* The user for the message went away, so give up. */ ipmi_free_recv_msg(recv_msg); } else { @@ -1733,7 +1749,7 @@ static struct timer_list ipmi_timer; /* Call every 100 ms. */ #define IPMI_TIMEOUT_TIME 100 -#define IPMI_TIMEOUT_JIFFIES (IPMI_TIMEOUT_TIME/(1000/HZ)) +#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ)/1000) /* Request events from the queue every second. Hopefully, in the future, IPMI will add a way to know immediately if an event is @@ -1813,18 +1829,48 @@ static void dummy_recv_done_handler(stru { } -static void send_panic_events(void) +#ifdef CONFIG_IPMI_PANIC_STRING +static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg) +{ + if ((msg->rsp[0] == (IPMI_NETFN_SENSOR_EVENT_RESPONSE << 2)) + && (msg->rsp[1] == IPMI_GET_EVENT_RECEIVER_CMD) + && (msg->rsp[2] == IPMI_CC_NO_ERROR)) + { + /* A get event receiver command, save it. */ + intf->event_receiver = msg->rsp[3]; + intf->event_receiver_lun = msg->rsp[4] & 0x3; + } +} + +static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg) +{ + if ((msg->rsp[0] == (IPMI_NETFN_APP_RESPONSE << 2)) + && (msg->rsp[1] == IPMI_GET_DEVICE_ID_CMD) + && (msg->rsp[2] == IPMI_CC_NO_ERROR)) + { + /* A get device id command, save if we are an event + receiver or generator. */ + intf->local_sel_device = (msg->rsp[8] >> 2) & 1; + intf->local_event_generator = (msg->rsp[8] >> 5) & 1; + } +} +#endif + +static void send_panic_events(char *str) { struct ipmi_msg msg; ipmi_smi_t intf; - unsigned char data[8]; + unsigned char data[16]; int i; - struct ipmi_system_interface_addr addr; + struct ipmi_system_interface_addr *si; + struct ipmi_addr addr; struct ipmi_smi_msg smi_msg; struct ipmi_recv_msg recv_msg; - addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - addr.channel = IPMI_BMC_CHANNEL; + si = (struct ipmi_system_interface_addr *) &addr; + si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + si->channel = IPMI_BMC_CHANNEL; + si->lun = 0; /* Fill in an event telling that we have failed. */ msg.netfn = 0x04; /* Sensor or Event. */ @@ -1837,12 +1883,13 @@ static void send_panic_events(void) data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */ data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */ - /* These used to have the first three bytes of the panic string, - but not only is that not terribly useful, it's not available - any more. */ - data[3] = 0; - data[6] = 0; - data[7] = 0; + /* Put a few breadcrumbs in. Hopefully later we can add more things + to make the panic events more useful. */ + if (str) { + data[3] = str[0]; + data[6] = str[1]; + data[7] = str[2]; + } smi_msg.done = dummy_smi_done_handler; recv_msg.done = dummy_recv_done_handler; @@ -1853,10 +1900,11 @@ static void send_panic_events(void) if (intf == NULL) continue; + /* Send the event announcing the panic. */ intf->handlers->set_run_to_completion(intf->send_info, 1); i_ipmi_request(NULL, intf, - (struct ipmi_addr *) &addr, + &addr, 0, &msg, &smi_msg, @@ -1865,6 +1913,130 @@ static void send_panic_events(void) intf->my_address, intf->my_lun); } + +#ifdef CONFIG_IPMI_PANIC_STRING + /* On every interface, dump a bunch of OEM event holding the + string. */ + if (!str) + return; + + for (i=0; ilocal_sel_device = 0; + intf->local_event_generator = 0; + intf->event_receiver = 0; + + /* Request the device info from the local MC. */ + msg.netfn = IPMI_NETFN_APP_REQUEST; + msg.cmd = IPMI_GET_DEVICE_ID_CMD; + msg.data = NULL; + msg.data_len = 0; + intf->null_user_handler = device_id_fetcher; + i_ipmi_request(NULL, + intf, + &addr, + 0, + &msg, + &smi_msg, + &recv_msg, + 0, + intf->my_address, + intf->my_lun); + + if (intf->local_event_generator) { + /* Request the event receiver from the local MC. */ + msg.netfn = IPMI_NETFN_SENSOR_EVENT_REQUEST; + msg.cmd = IPMI_GET_EVENT_RECEIVER_CMD; + msg.data = NULL; + msg.data_len = 0; + intf->null_user_handler = event_receiver_fetcher; + i_ipmi_request(NULL, + intf, + &addr, + 0, + &msg, + &smi_msg, + &recv_msg, + 0, + intf->my_address, + intf->my_lun); + } + intf->null_user_handler = NULL; + + /* Validate the event receiver. The low bit must not + be 1 (it must be a valid IPMB address), it cannot + be zero, and it must not be my address. */ + if (((intf->event_receiver & 1) == 0) + && (intf->event_receiver != 0) + && (intf->event_receiver != intf->my_address)) + { + /* The event receiver is valid, send an IPMB + message. */ + ipmb = (struct ipmi_ipmb_addr *) &addr; + ipmb->addr_type = IPMI_IPMB_ADDR_TYPE; + ipmb->channel = 0; /* FIXME - is this right? */ + ipmb->lun = intf->event_receiver_lun; + ipmb->slave_addr = intf->event_receiver; + } else if (intf->local_sel_device) { + /* The event receiver was not valid (or was + me), but I am an SEL device, just dump it + in my SEL. */ + si = (struct ipmi_system_interface_addr *) &addr; + si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + si->channel = IPMI_BMC_CHANNEL; + si->lun = 0; + } else + continue; /* No where to send the event. */ + + + msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */ + msg.cmd = IPMI_ADD_SEL_ENTRY_CMD; + msg.data = data; + msg.data_len = 16; + + j = 0; + while (*p) { + int size = strlen(p); + + if (size > 11) + size = 11; + data[0] = 0; + data[1] = 0; + data[2] = 0xf0; /* OEM event without timestamp. */ + data[3] = intf->my_address; + data[4] = j++; /* sequence # */ + /* Always give 11 bytes, so strncpy will fill + it with zeroes for me. */ + strncpy(data+5, p, 11); + p += size; + + i_ipmi_request(NULL, + intf, + &addr, + 0, + &msg, + &smi_msg, + &recv_msg, + 0, + intf->my_address, + intf->my_lun); + } + } +#endif /* CONFIG_IPMI_PANIC_STRING */ } #endif /* CONFIG_IPMI_PANIC_EVENT */ @@ -1891,7 +2063,7 @@ static int panic_event(struct notifier_b } #ifdef CONFIG_IPMI_PANIC_EVENT - send_panic_events(); + send_panic_events(ptr); #endif return NOTIFY_DONE; diff -prauN linux-2.6.0-test7/drivers/char/n_tty.c wli-2.6.0-test7-bk5-36/drivers/char/n_tty.c --- linux-2.6.0-test7/drivers/char/n_tty.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/n_tty.c 2003-10-14 02:49:46.000000000 -0700 @@ -974,8 +974,7 @@ do_it_again: /* NOTE: not yet done after every sleep pending a thorough check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ - if (file->f_op->write != redirected_tty_write && - process_tty(current) == tty) { + if (file->f_op->write != redirected_tty_write && current->tty == tty) { if (tty->pgrp <= 0) printk("read_chan: tty->pgrp <= 0!\n"); else if (process_group(current) != tty->pgrp) { diff -prauN linux-2.6.0-test7/drivers/char/pcmcia/synclink_cs.c wli-2.6.0-test7-bk5-36/drivers/char/pcmcia/synclink_cs.c --- linux-2.6.0-test7/drivers/char/pcmcia/synclink_cs.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/pcmcia/synclink_cs.c 2003-10-14 02:49:46.000000000 -0700 @@ -4232,7 +4232,7 @@ void mgslpc_sppp_init(MGSLPC_INFO *info) d->tx_timeout = mgslpc_sppp_tx_timeout; d->watchdog_timeo = 10*HZ; - if (register_netdev(d) == -1) { + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); return; diff -prauN linux-2.6.0-test7/drivers/char/rocket.c wli-2.6.0-test7-bk5-36/drivers/char/rocket.c --- linux-2.6.0-test7/drivers/char/rocket.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/rocket.c 2003-10-14 02:49:46.000000000 -0700 @@ -953,7 +953,7 @@ static int rp_open(struct tty_struct *tt /* * Info->count is now 1; so it's safe to sleep now. */ - info->session = process_session(current); + info->session = current->session; info->pgrp = process_group(current); if ((info->flags & ROCKET_INITIALIZED) == 0) { diff -prauN linux-2.6.0-test7/drivers/char/synclink.c wli-2.6.0-test7-bk5-36/drivers/char/synclink.c --- linux-2.6.0-test7/drivers/char/synclink.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/synclink.c 2003-10-14 02:49:46.000000000 -0700 @@ -7847,7 +7847,7 @@ void mgsl_sppp_init(struct mgsl_struct * d->tx_timeout = mgsl_sppp_tx_timeout; d->watchdog_timeo = 10*HZ; - if (register_netdev(d) == -1) { + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); return; diff -prauN linux-2.6.0-test7/drivers/char/synclinkmp.c wli-2.6.0-test7-bk5-36/drivers/char/synclinkmp.c --- linux-2.6.0-test7/drivers/char/synclinkmp.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/synclinkmp.c 2003-10-14 02:49:46.000000000 -0700 @@ -1653,7 +1653,7 @@ static void sppp_init(SLMP_INFO *info) d->tx_timeout = sppp_cb_tx_timeout; d->watchdog_timeo = 10*HZ; - if (register_netdev(d) == -1) { + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(info->netdev); return; diff -prauN linux-2.6.0-test7/drivers/char/tty_io.c wli-2.6.0-test7-bk5-36/drivers/char/tty_io.c --- linux-2.6.0-test7/drivers/char/tty_io.c 2003-10-08 12:24:15.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/tty_io.c 2003-10-14 03:12:56.000000000 -0700 @@ -316,7 +316,7 @@ struct tty_driver *get_tty_driver(dev_t */ int tty_check_change(struct tty_struct * tty) { - if (process_tty(current) != tty) + if (current->tty != tty) return 0; if (tty->pgrp <= 0) { printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); @@ -481,16 +481,15 @@ void do_tty_hangup(void *data) read_lock(&tasklist_lock); if (tty->session > 0) { - struct list_head *l; - for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) { - if (process_tty(p) == tty) - p->signal->tty = NULL; - if (!process_session_leader(p)) + for_each_task_pid(tty->session, PIDTYPE_SID, p, pid) { + if (p->tty == tty) + p->tty = NULL; + if (!p->leader) continue; send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); if (tty->pgrp > 0) - p->signal->tty_old_pgrp = tty->pgrp; + p->tty_old_pgrp = tty->pgrp; } } read_unlock(&tasklist_lock); @@ -560,22 +559,21 @@ EXPORT_SYMBOL(tty_hung_up_p); void disassociate_ctty(int on_exit) { struct tty_struct *tty; - struct task_struct *p; - struct list_head *l; + task_t *p; struct pid *pid; int tty_pgrp = -1; lock_kernel(); - tty = process_tty(current); + tty = current->tty; if (tty) { tty_pgrp = tty->pgrp; if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) tty_vhangup(tty); } else { - if (current->signal->tty_old_pgrp) { - kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); - kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); + if (current->tty_old_pgrp) { + kill_pg(current->tty_old_pgrp, SIGHUP, on_exit); + kill_pg(current->tty_old_pgrp, SIGCONT, on_exit); } unlock_kernel(); return; @@ -586,13 +584,13 @@ void disassociate_ctty(int on_exit) kill_pg(tty_pgrp, SIGCONT, on_exit); } - current->signal->tty_old_pgrp = 0; + current->tty_old_pgrp = 0; tty->session = 0; tty->pgrp = -1; read_lock(&tasklist_lock); - for_each_task_pid(process_session(current), PIDTYPE_SID, p, l, pid) - p->signal->tty = NULL; + for_each_task_pid(current->session, PIDTYPE_SID, p, pid) + p->tty = NULL; read_unlock(&tasklist_lock); unlock_kernel(); } @@ -1214,16 +1212,15 @@ static void release_dev(struct file * fi * tty. */ if (tty_closing || o_tty_closing) { - struct task_struct *p; - struct list_head *l; + task_t *p; struct pid *pid; read_lock(&tasklist_lock); - for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) - p->signal->tty = NULL; + for_each_task_pid(tty->session, PIDTYPE_SID, p, pid) + p->tty = NULL; if (o_tty) - for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid) - p->signal->tty = NULL; + for_each_task_pid(o_tty->session, PIDTYPE_SID, p, pid) + p->tty = NULL; read_unlock(&tasklist_lock); } @@ -1294,10 +1291,10 @@ static int tty_open(struct inode * inode retry_open: noctty = filp->f_flags & O_NOCTTY; if (device == MKDEV(TTYAUX_MAJOR,0)) { - if (!process_tty(current)) + if (!current->tty) return -ENXIO; - driver = process_tty(current)->driver; - index = process_tty(current)->index; + driver = current->tty->driver; + index = current->tty->index; filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ goto got_driver; @@ -1391,13 +1388,15 @@ got_driver: filp->f_op = &tty_fops; goto retry_open; } - if (!noctty && process_session_leader(current) && - !process_tty(current) && tty->session == 0) { + if (!noctty && + current->leader && + !current->tty && + tty->session == 0) { task_lock(current); - current->signal->tty = tty; + current->tty = tty; task_unlock(current); - current->signal->tty_old_pgrp = 0; - tty->session = process_session(current); + current->tty_old_pgrp = 0; + tty->session = current->session; tty->pgrp = process_group(current); } return 0; @@ -1455,7 +1454,7 @@ static int tiocsti(struct tty_struct *tt { char ch, mbz = 0; - if ((process_tty(current) != tty) && !capable(CAP_SYS_ADMIN)) + if ((current->tty != tty) && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ch, arg)) return -EFAULT; @@ -1537,18 +1536,17 @@ static int fionbio(struct file *file, in static int tiocsctty(struct tty_struct *tty, int arg) { - struct list_head *l; struct pid *pid; task_t *p; - if (process_session_leader(current) && - (process_session(current) == tty->session)) + if (current->leader && + (current->session == tty->session)) return 0; /* * The process must be a session leader and * not have a controlling tty already. */ - if (!process_session_leader(current) || process_tty(current)) + if (!current->leader || current->tty) return -EPERM; if (tty->session > 0) { /* @@ -1561,17 +1559,17 @@ static int tiocsctty(struct tty_struct * */ read_lock(&tasklist_lock); - for_each_task_pid(tty->session, PIDTYPE_SID, p, l, pid) - p->signal->tty = NULL; + for_each_task_pid(tty->session, PIDTYPE_SID, p, pid) + p->tty = NULL; read_unlock(&tasklist_lock); } else return -EPERM; } task_lock(current); - current->signal->tty = tty; + current->tty = tty; task_unlock(current); - current->signal->tty_old_pgrp = 0; - tty->session = process_session(current); + current->tty_old_pgrp = 0; + tty->session = current->session; tty->pgrp = process_group(current); return 0; } @@ -1582,13 +1580,12 @@ static int tiocgpgrp(struct tty_struct * * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. */ - if (tty == real_tty && process_tty(current) != real_tty) + if (tty == real_tty && current->tty != real_tty) return -ENOTTY; return put_user(real_tty->pgrp, arg); } -static int tiocspgrp(struct tty_struct *tty, - struct tty_struct *real_tty, pid_t *arg) +static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t *arg) { pid_t pgrp; int retval = tty_check_change(real_tty); @@ -1597,14 +1594,15 @@ static int tiocspgrp(struct tty_struct * return -ENOTTY; if (retval) return retval; - if (!process_tty(current) || (process_tty(current) != real_tty) || - (real_tty->session != process_session(current))) + if (!current->tty || + (current->tty != real_tty) || + (real_tty->session != current->session)) return -ENOTTY; if (get_user(pgrp, (pid_t *) arg)) return -EFAULT; if (pgrp < 0) return -EINVAL; - if (session_of_pgrp(pgrp) != process_session(current)) + if (session_of_pgrp(pgrp) != current->session) return -EPERM; real_tty->pgrp = pgrp; return 0; @@ -1616,7 +1614,7 @@ static int tiocgsid(struct tty_struct *t * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. */ - if (tty == real_tty && process_tty(current) != real_tty) + if (tty == real_tty && current->tty != real_tty) return -ENOTTY; if (real_tty->session <= 0) return -ENOTTY; @@ -1774,12 +1772,12 @@ int tty_ioctl(struct inode * inode, stru clear_bit(TTY_EXCLUSIVE, &tty->flags); return 0; case TIOCNOTTY: - if (process_tty(current) != tty) + if (current->tty != tty) return -ENOTTY; - if (process_session_leader(current)) + if (current->leader) disassociate_ctty(0); task_lock(current); - current->signal->tty = NULL; + current->tty = NULL; task_unlock(current); return 0; case TIOCSCTTY: @@ -1867,8 +1865,7 @@ static void __do_SAK(void *arg) tty_hangup(tty); #else struct tty_struct *tty = arg; - struct task_struct *p; - struct list_head *l; + task_t *p; struct pid *pid; int session; int i; @@ -1882,11 +1879,11 @@ static void __do_SAK(void *arg) if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); read_lock(&tasklist_lock); - for_each_task_pid(session, PIDTYPE_SID, p, l, pid) { - if (process_tty(p) == tty || session > 0) { + for_each_task_pid(session, PIDTYPE_SID, p, pid) { + if (p->tty == tty || session > 0) { printk(KERN_NOTICE "SAK: killed process %d" - " (%s): process_session(p)==tty->session\n", - p->pid, p->comm); + " (%s): p->session==tty->session\n", + p->pid, p->comm); send_sig(SIGKILL, p, 1); continue; } diff -prauN linux-2.6.0-test7/drivers/char/vt.c wli-2.6.0-test7-bk5-36/drivers/char/vt.c --- linux-2.6.0-test7/drivers/char/vt.c 2003-10-08 12:24:40.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/vt.c 2003-10-14 02:49:46.000000000 -0700 @@ -2226,7 +2226,7 @@ int tioclinux(struct tty_struct *tty, un if (tty->driver->type != TTY_DRIVER_TYPE_CONSOLE) return -EINVAL; - if (process_tty(current) != tty && !capable(CAP_SYS_ADMIN)) + if (current->tty != tty && !capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(type, (char *)arg)) return -EFAULT; diff -prauN linux-2.6.0-test7/drivers/char/vt_ioctl.c wli-2.6.0-test7-bk5-36/drivers/char/vt_ioctl.c --- linux-2.6.0-test7/drivers/char/vt_ioctl.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/char/vt_ioctl.c 2003-10-14 02:49:46.000000000 -0700 @@ -380,7 +380,7 @@ int vt_ioctl(struct tty_struct *tty, str * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. */ perm = 0; - if (process_tty(current) == tty || capable(CAP_SYS_TTY_CONFIG)) + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) perm = 1; kbd = kbd_table + console; @@ -1188,3 +1188,4 @@ void change_console(unsigned int new_con complete_change_console(new_console); } + diff -prauN linux-2.6.0-test7/drivers/i2c/busses/Kconfig wli-2.6.0-test7-bk5-36/drivers/i2c/busses/Kconfig --- linux-2.6.0-test7/drivers/i2c/busses/Kconfig 2003-10-08 12:24:42.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/busses/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -157,7 +157,7 @@ config I2C_PHILIPSPAR config I2C_PIIX4 tristate "Intel PIIX4" - depends on I2C && PCI && EXPERIMENTAL + depends on I2C && PCI && EXPERIMENTAL && !64BIT help If you say yes to this option, support will be included for the Intel PIIX4 family of mainboard I2C interfaces. Specifically, the following @@ -248,11 +248,11 @@ config I2C_SIS5595 will be called i2c-sis5595. config I2C_SIS630 - tristate "SiS 630" + tristate "SiS 630/730" depends on I2C && PCI && EXPERIMENTAL help If you say yes to this option, support will be included for the - SiS630 SMBus (a subset of I2C) interface. + SiS630 and SiS730 SMBus (a subset of I2C) interface. This driver can also be built as a module. If so, the module will be called i2c-sis630. diff -prauN linux-2.6.0-test7/drivers/i2c/busses/i2c-sis630.c wli-2.6.0-test7-bk5-36/drivers/i2c/busses/i2c-sis630.c --- linux-2.6.0-test7/drivers/i2c/busses/i2c-sis630.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/busses/i2c-sis630.c 2003-10-14 02:49:46.000000000 -0700 @@ -25,10 +25,10 @@ Fixed the typo in sis630_access (Thanks to Mark M. Hoffman) Changed sis630_transaction.(Thanks to Mark M. Hoffman) 18.09.2002 - Added SIS730 as supported + Added SIS730 as supported. 21.09.2002 Added high_clock module option.If this option is set - used Host Master Clock 56KHz (default 14KHz).For now we are save old Host + used Host Master Clock 56KHz (default 14KHz).For now we save old Host Master Clock and after transaction completed restore (otherwise it's confuse BIOS and hung Machine). 24.09.2002 @@ -95,12 +95,22 @@ /* insmod parameters */ static int high_clock = 0; +static int force = 0; MODULE_PARM(high_clock, "i"); MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz)."); +MODULE_PARM(force, "i"); +MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!"); - +/* acpi base address */ static unsigned short acpi_base = 0; +/* supported chips */ +static int supported[] = { + PCI_DEVICE_ID_SI_630, + PCI_DEVICE_ID_SI_730, + 0 /* terminates the list */ +}; + static inline u8 sis630_read(u8 reg) { return inb(acpi_base + reg); @@ -277,6 +287,10 @@ static int sis630_block_data(struct i2c_ if (len == 0) data->block[0] = sis630_read(SMB_COUNT); + /* just to be sure */ + if (data->block[0] > 32) + data->block[0] = 32; + dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]); for (i=0; i < 8 && len < data->block[0]; i++,len++) { @@ -372,16 +386,26 @@ static u32 sis630_func(struct i2c_adapte I2C_FUNC_SMBUS_BLOCK_DATA; } -static int sis630_setup(struct pci_dev *dummy) +static int sis630_setup(struct pci_dev *sis630_dev) { unsigned char b; - struct pci_dev *sis630_dev = NULL; - int retval = -ENODEV; + struct pci_dev *dummy = NULL; + int retval = -ENODEV, i; - /* We need ISA bridge and not pci device passed in. */ - sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev); - if (!sis630_dev) { - dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n"); + /* check for supported SiS devices */ + for (i=0; supported[i] > 0 ; i++) { + if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy))) + break; /* found */ + } + + if (dummy) { + pci_dev_put(dummy); + } + else if (force > 0) { + dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but " + "loading because of force option enabled\n"); + } + else { return -ENODEV; } @@ -389,19 +413,19 @@ static int sis630_setup(struct pci_dev * Enable ACPI first , so we can accsess reg 74-75 in acpi io space and read acpi base addr */ - if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { + if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); goto exit; } - /* if ACPI already enabled , do nothing */ if (!(b & 0x80) && - !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { + pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); goto exit; } + /* Determine the ACPI base address */ - if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { + if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); goto exit; } @@ -418,7 +442,8 @@ static int sis630_setup(struct pci_dev * retval = 0; exit: - pci_dev_put(sis630_dev); + if (retval) + acpi_base = 0; return retval; } @@ -432,19 +457,18 @@ static struct i2c_algorithm smbus_algori static struct i2c_adapter sis630_adapter = { .owner = THIS_MODULE, + .class = I2C_ADAP_CLASS_SMBUS, .name = "unset", .algo = &smbus_algorithm, }; static struct pci_device_id sis630_ids[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) }, - { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) }, + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, { 0, } }; static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id) { - if (sis630_setup(dev)) { dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n"); return -ENODEV; @@ -461,7 +485,11 @@ static int __devinit sis630_probe(struct static void __devexit sis630_remove(struct pci_dev *dev) { - i2c_del_adapter(&sis630_adapter); + if (acpi_base) { + i2c_del_adapter(&sis630_adapter); + release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION); + acpi_base = 0; + } } @@ -481,7 +509,6 @@ static int __init i2c_sis630_init(void) static void __exit i2c_sis630_exit(void) { pci_unregister_driver(&sis630_driver); - release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION); } diff -prauN linux-2.6.0-test7/drivers/i2c/chips/Kconfig wli-2.6.0-test7-bk5-36/drivers/i2c/chips/Kconfig --- linux-2.6.0-test7/drivers/i2c/chips/Kconfig 2003-10-08 12:24:07.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/Kconfig 2003-10-14 02:49:46.000000000 -0700 @@ -15,7 +15,7 @@ config SENSORS_ADM1021 help If you say yes here you get support for Analog Devices ADM1021 and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, - Genesys Logic GL523SM, National Semi LM84, TI THMC10, + Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, and the XEON processor built-in sensor. This driver can also be built as a module. If so, the module @@ -34,30 +34,30 @@ config SENSORS_EEPROM will be called eeprom. config SENSORS_IT87 - tristate "National Semiconductors IT87 and compatibles" + tristate "ITE IT87xx and compatibles" depends on I2C && EXPERIMENTAL select I2C_SENSOR help - If you say yes here you get support for National Semiconductor IT87 - sensor chips and clones: IT8705F, IT8712F and SiS960. + If you say yes here you get support for ITE IT87xx sensor chips + and clones: SiS960. This driver can also be built as a module. If so, the module will be called it87. config SENSORS_LM75 - tristate "National Semiconductors LM75 and compatibles" + tristate "National Semiconductor LM75 and compatibles" depends on I2C && EXPERIMENTAL select I2C_SENSOR help If you say yes here you get support for National Semiconductor LM75 sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon - TCN75, and National Semi LM77. + TCN75, and National Semiconductor LM77. This driver can also be built as a module. If so, the module will be called lm75. config SENSORS_LM78 - tristate "National Semiconductors LM78 and compatibles" + tristate "National Semiconductor LM78 and compatibles" depends on I2C && EXPERIMENTAL select I2C_SENSOR help @@ -69,7 +69,7 @@ config SENSORS_LM78 will be called lm78. config SENSORS_LM85 - tristate "National Semiconductors LM85 and compatibles" + tristate "National Semiconductor LM85 and compatibles" depends on I2C && EXPERIMENTAL select I2C_SENSOR help diff -prauN linux-2.6.0-test7/drivers/i2c/chips/adm1021.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/adm1021.c --- linux-2.6.0-test7/drivers/i2c/chips/adm1021.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/adm1021.c 2003-10-14 02:49:46.000000000 -0700 @@ -322,6 +322,10 @@ static int adm1021_detect(struct i2c_ada if ((err = i2c_attach_client(new_client))) goto error3; + /* Initialize the ADM1021 chip */ + adm1021_init_client(new_client); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_temp_max1); device_create_file(&new_client->dev, &dev_attr_temp_min1); device_create_file(&new_client->dev, &dev_attr_temp_input1); @@ -332,8 +336,6 @@ static int adm1021_detect(struct i2c_ada if (data->type == adm1021) device_create_file(&new_client->dev, &dev_attr_die_code); - /* Initialize the ADM1021 chip */ - adm1021_init_client(new_client); return 0; error3: diff -prauN linux-2.6.0-test7/drivers/i2c/chips/it87.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/it87.c --- linux-2.6.0-test7/drivers/i2c/chips/it87.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/it87.c 2003-10-14 02:49:46.000000000 -0700 @@ -701,7 +701,10 @@ int it87_detect(struct i2c_adapter *adap if ((err = i2c_attach_client(new_client))) goto ERROR1; - /* register sysfs hooks */ + /* Initialize the IT87 chip */ + it87_init_client(new_client, data); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_input1); device_create_file(&new_client->dev, &dev_attr_in_input2); @@ -750,8 +753,6 @@ int it87_detect(struct i2c_adapter *adap device_create_file(&new_client->dev, &dev_attr_fan_div3); device_create_file(&new_client->dev, &dev_attr_alarm); - /* Initialize the IT87 chip */ - it87_init_client(new_client, data); return 0; ERROR1: diff -prauN linux-2.6.0-test7/drivers/i2c/chips/lm75.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm75.c --- linux-2.6.0-test7/drivers/i2c/chips/lm75.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm75.c 2003-10-14 02:49:46.000000000 -0700 @@ -204,11 +204,14 @@ static int lm75_detect(struct i2c_adapte if ((err = i2c_attach_client(new_client))) goto exit_free; + /* Initialize the LM75 chip */ + lm75_init_client(new_client); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_temp_max); device_create_file(&new_client->dev, &dev_attr_temp_min); device_create_file(&new_client->dev, &dev_attr_temp_input); - lm75_init_client(new_client); return 0; exit_free: diff -prauN linux-2.6.0-test7/drivers/i2c/chips/lm78.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm78.c --- linux-2.6.0-test7/drivers/i2c/chips/lm78.c 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm78.c 2003-10-14 02:49:46.000000000 -0700 @@ -648,7 +648,10 @@ int lm78_detect(struct i2c_adapter *adap if ((err = i2c_attach_client(new_client))) goto ERROR2; - /* register sysfs hooks */ + /* Initialize the LM78 chip */ + lm78_init_client(new_client); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_min0); device_create_file(&new_client->dev, &dev_attr_in_max0); @@ -685,8 +688,6 @@ int lm78_detect(struct i2c_adapter *adap device_create_file(&new_client->dev, &dev_attr_alarms); device_create_file(&new_client->dev, &dev_attr_vid); - /* Initialize the LM78 chip */ - lm78_init_client(new_client); return 0; ERROR2: diff -prauN linux-2.6.0-test7/drivers/i2c/chips/lm85.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm85.c --- linux-2.6.0-test7/drivers/i2c/chips/lm85.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/lm85.c 2003-10-14 02:49:46.000000000 -0700 @@ -888,6 +888,10 @@ int lm85_detect(struct i2c_adapter *adap /* Set the VRM version */ data->vrm = LM85_INIT_VRM ; + /* Initialize the LM85 chip */ + lm85_init_client(new_client); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_fan_input1); device_create_file(&new_client->dev, &dev_attr_fan_input2); device_create_file(&new_client->dev, &dev_attr_fan_input3); @@ -930,8 +934,6 @@ int lm85_detect(struct i2c_adapter *adap device_create_file(&new_client->dev, &dev_attr_vid); device_create_file(&new_client->dev, &dev_attr_alarms); - /* Initialize the LM85 chip */ - lm85_init_client(new_client); return 0; /* Error out and cleanup code */ diff -prauN linux-2.6.0-test7/drivers/i2c/chips/via686a.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/via686a.c --- linux-2.6.0-test7/drivers/i2c/chips/via686a.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/via686a.c 2003-10-14 02:49:46.000000000 -0700 @@ -735,7 +735,10 @@ static int via686a_detect(struct i2c_ada if ((err = i2c_attach_client(new_client))) goto ERROR3; - /* register sysfs hooks */ + /* Initialize the VIA686A chip */ + via686a_init_client(new_client); + + /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_in_input0); device_create_file(&new_client->dev, &dev_attr_in_input1); device_create_file(&new_client->dev, &dev_attr_in_input2); @@ -768,8 +771,6 @@ static int via686a_detect(struct i2c_ada device_create_file(&new_client->dev, &dev_attr_fan_div2); device_create_file(&new_client->dev, &dev_attr_alarm); - /* Initialize the VIA686A chip */ - via686a_init_client(new_client); return 0; ERROR3: diff -prauN linux-2.6.0-test7/drivers/i2c/chips/w83781d.c wli-2.6.0-test7-bk5-36/drivers/i2c/chips/w83781d.c --- linux-2.6.0-test7/drivers/i2c/chips/w83781d.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/chips/w83781d.c 2003-10-14 02:49:47.000000000 -0700 @@ -1346,6 +1346,10 @@ w83781d_detect(struct i2c_adapter *adapt data->lm75[1] = NULL; } + /* Initialize the chip */ + w83781d_init_client(new_client); + + /* Register sysfs hooks */ device_create_file_in(new_client, 0); if (kind != w83783s && kind != w83697hf) device_create_file_in(new_client, 1); @@ -1408,8 +1412,6 @@ w83781d_detect(struct i2c_adapter *adapt } #endif - /* Initialize the chip */ - w83781d_init_client(new_client); return 0; ERROR3: diff -prauN linux-2.6.0-test7/drivers/i2c/i2c-dev.c wli-2.6.0-test7-bk5-36/drivers/i2c/i2c-dev.c --- linux-2.6.0-test7/drivers/i2c/i2c-dev.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/i2c/i2c-dev.c 2003-10-14 02:49:47.000000000 -0700 @@ -49,6 +49,7 @@ struct i2c_dev { int minor; struct i2c_adapter *adap; struct class_device class_dev; + struct completion released; /* FIXME, we need a class_device_unregister() */ }; #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) @@ -112,7 +113,6 @@ static void return_i2c_dev(struct i2c_de spin_lock(&i2c_dev_array_lock); i2c_dev_array[i2c_dev->minor] = NULL; spin_unlock(&i2c_dev_array_lock); - kfree(i2c_dev); } static ssize_t show_dev(struct class_device *class_dev, char *buf) @@ -421,8 +421,15 @@ static struct file_operations i2cdev_fop .release = i2cdev_release, }; +static void release_i2c_dev(struct class_device *dev) +{ + struct i2c_dev *i2c_dev = to_i2c_dev(dev); + complete(&i2c_dev->released); +} + static struct class i2c_dev_class = { - .name = "i2c-dev", + .name = "i2c-dev", + .release = &release_i2c_dev, }; static int i2cdev_attach_adapter(struct i2c_adapter *adap) @@ -453,6 +460,7 @@ static int i2cdev_attach_adapter(struct return 0; error: return_i2c_dev(i2c_dev); + kfree(i2c_dev); return retval; } @@ -464,9 +472,12 @@ static int i2cdev_detach_adapter(struct if (!i2c_dev) return -ENODEV; - class_device_unregister(&i2c_dev->class_dev); + init_completion(&i2c_dev->released); devfs_remove("i2c/%d", i2c_dev->minor); return_i2c_dev(i2c_dev); + class_device_unregister(&i2c_dev->class_dev); + wait_for_completion(&i2c_dev->released); + kfree(i2c_dev); dev_dbg(&adap->dev, "Adapter unregistered\n"); return 0; diff -prauN linux-2.6.0-test7/drivers/macintosh/adbhid.c wli-2.6.0-test7-bk5-36/drivers/macintosh/adbhid.c --- linux-2.6.0-test7/drivers/macintosh/adbhid.c 2003-10-08 12:24:53.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/macintosh/adbhid.c 2003-10-14 02:49:47.000000000 -0700 @@ -611,8 +611,8 @@ adbhid_input_register(int id, int defaul /* HACK WARNING!! This should go away as soon there is an utility * to control that for event devices. */ - adbhid[id]->input.rep[REP_DELAY] = HZ/2; /* input layer default: HZ/4 */ - adbhid[id]->input.rep[REP_PERIOD] = HZ/15; /* input layer default: HZ/33 */ + adbhid[id]->input.rep[REP_DELAY] = 500; /* input layer default: 250 */ + adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */ } } diff -prauN linux-2.6.0-test7/drivers/media/common/saa7146_fops.c wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_fops.c --- linux-2.6.0-test7/drivers/media/common/saa7146_fops.c 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_fops.c 2003-10-14 02:49:47.000000000 -0700 @@ -61,8 +61,14 @@ void saa7146_buffer_finish(struct saa714 } DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state)); + DEB_EE(("q->curr:%p\n",q->curr)); /* finish current buffer */ + if (NULL == q->curr) { + DEB_D(("aiii. no current buffer\n")); + return; + } + q->curr->vb.state = state; do_gettimeofday(&q->curr->vb.ts); wake_up(&q->curr->vb.done); @@ -221,9 +227,12 @@ static int fops_open(struct inode *inode fh->dev = dev; fh->type = type; - saa7146_video_uops.open(dev,fh); - if( 0 != BOARD_CAN_DO_VBI(dev) ) { + if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + DEB_S(("initializing vbi...\n")); saa7146_vbi_uops.open(dev,fh); + } else { + DEB_S(("initializing video...\n")); + saa7146_video_uops.open(dev,fh); } result = 0; @@ -245,9 +254,10 @@ static int fops_release(struct inode *in if (down_interruptible(&saa7146_devices_lock)) return -ERESTARTSYS; - saa7146_video_uops.release(dev,fh,file); - if( 0 != BOARD_CAN_DO_VBI(dev) ) { + if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { saa7146_vbi_uops.release(dev,fh,file); + } else { + saa7146_video_uops.release(dev,fh,file); } module_put(dev->ext->module); @@ -332,11 +342,11 @@ static ssize_t fops_read(struct file *fi switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count)); +// DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count)); return saa7146_video_uops.read(file,data,count,ppos); } case V4L2_BUF_TYPE_VBI_CAPTURE: { - DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); +// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); return saa7146_vbi_uops.read(file,data,count,ppos); } break; @@ -443,7 +453,7 @@ int saa7146_register_device(struct video { struct saa7146_vv *vv = dev->vv_data; - DEB_EE(("dev:%p, name:'%s'\n",dev,name)); + DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); *vid = device_template; strlcpy(vid->name, name, sizeof(vid->name)); @@ -451,7 +461,7 @@ int saa7146_register_device(struct video // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr"); if (video_register_device(vid,type,-1) < 0) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); + ERR(("cannot register v4l2 device. skipping.\n")); return -1; } diff -prauN linux-2.6.0-test7/drivers/media/common/saa7146_vbi.c wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_vbi.c --- linux-2.6.0-test7/drivers/media/common/saa7146_vbi.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_vbi.c 2003-10-14 02:49:47.000000000 -0700 @@ -38,8 +38,14 @@ static int vbi_workaround(struct saa7146 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); /* BXO = 1h, BRS to outbound */ WRITE_RPS1(0xc000008c); - /* wait for vbi_a */ + /* wait for vbi_a or vbi_b*/ + if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) { + DEB_D(("...using port b\n")); + WRITE_RPS1(CMD_PAUSE | MASK_09); + } else { + DEB_D(("...using port a\n")); WRITE_RPS1(CMD_PAUSE | MASK_10); + } /* upload brs */ WRITE_RPS1(CMD_UPLOAD | MASK_08); /* load brs-control register */ @@ -106,7 +112,7 @@ static int vbi_workaround(struct saa7146 if(signal_pending(current)) { - DEB_VBI(("aborted.\n")); + DEB_VBI(("aborted (rps:0x%08x).\n",saa7146_read(dev,RPS_ADDR1))); /* stop rps1 for sure */ saa7146_write(dev, MC1, MASK_29); @@ -316,6 +322,11 @@ static void vbi_stop(struct saa7146_fh * saa7146_write(dev, MC1, MASK_20); vv->vbi_streaming = NULL; + + del_timer(&vv->vbi_q.timeout); + del_timer(&fh->vbi_read_timeout); + + DEB_VBI(("out\n")); spin_unlock_irqrestore(&dev->slock, flags); } @@ -371,7 +382,10 @@ static void vbi_open(struct saa7146_dev fh->vbi_read_timeout.function = vbi_read_timeout; fh->vbi_read_timeout.data = (unsigned long)fh; + /* fixme: enable this again, if the dvb-c w/ analog module work properly */ +/* vbi_workaround(dev); +*/ } static void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file) diff -prauN linux-2.6.0-test7/drivers/media/common/saa7146_video.c wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_video.c --- linux-2.6.0-test7/drivers/media/common/saa7146_video.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/common/saa7146_video.c 2003-10-14 02:49:47.000000000 -0700 @@ -1319,7 +1319,7 @@ static int buffer_prepare(struct file *f saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); } - err = videobuf_iolock(dev->pci,&buf->vb,NULL); + err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb); if (err) goto oops; err = saa7146_pgtable_build(dev,buf); diff -prauN linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_i2c.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_i2c.c --- linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_i2c.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_i2c.c 2003-10-14 02:49:47.000000000 -0700 @@ -32,8 +32,9 @@ struct dvb_i2c_device { struct list_head list_head; struct module *owner; - int (*attach) (struct dvb_i2c_bus *i2c); - void (*detach) (struct dvb_i2c_bus *i2c); + int (*attach) (struct dvb_i2c_bus *i2c, void **data); + void (*detach) (struct dvb_i2c_bus *i2c, void *data); + void *data; }; LIST_HEAD(dvb_i2c_buslist); @@ -66,7 +67,7 @@ static void try_attach_device (struct dv return; } - if (dev->attach (i2c) == 0) { + if (dev->attach (i2c, &dev->data) == 0) { register_i2c_client (i2c, dev); } else { if (dev->owner) @@ -77,7 +78,7 @@ static void try_attach_device (struct dv static void detach_device (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) { - dev->detach (i2c); + dev->detach (i2c, dev->data); if (dev->owner) module_put (dev->owner); @@ -229,8 +230,8 @@ void dvb_unregister_i2c_bus (int (*xfer) int dvb_register_i2c_device (struct module *owner, - int (*attach) (struct dvb_i2c_bus *i2c), - void (*detach) (struct dvb_i2c_bus *i2c)) + int (*attach) (struct dvb_i2c_bus *i2c, void **data), + void (*detach) (struct dvb_i2c_bus *i2c, void *data)) { struct dvb_i2c_device *entry; @@ -256,7 +257,7 @@ int dvb_register_i2c_device (struct modu } -int dvb_unregister_i2c_device (int (*attach) (struct dvb_i2c_bus *i2c)) +int dvb_unregister_i2c_device (int (*attach) (struct dvb_i2c_bus *i2c, void **data)) { struct list_head *entry, *n; diff -prauN linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_i2c.h wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_i2c.h --- linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_i2c.h 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_i2c.h 2003-10-14 02:49:47.000000000 -0700 @@ -54,10 +54,10 @@ void dvb_unregister_i2c_bus (int (*xfer) extern int dvb_register_i2c_device (struct module *owner, - int (*attach) (struct dvb_i2c_bus *i2c), - void (*detach) (struct dvb_i2c_bus *i2c)); + int (*attach) (struct dvb_i2c_bus *i2c, void **data), + void (*detach) (struct dvb_i2c_bus *i2c, void *data)); -extern int dvb_unregister_i2c_device (int (*attach) (struct dvb_i2c_bus *i2c)); +extern int dvb_unregister_i2c_device (int (*attach) (struct dvb_i2c_bus *i2c, void **data)); #endif diff -prauN linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_net.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_net.c --- linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_net.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_net.c 2003-10-14 02:49:47.000000000 -0700 @@ -456,7 +456,7 @@ static struct net_device_stats * dvb_net } -static void dvb_net_setup(struct net_device *dev) +static int dvb_net_init_dev (struct net_device *dev) { ether_setup(dev); @@ -472,8 +472,11 @@ static void dvb_net_setup(struct net_dev dev->hard_header_cache = NULL; dev->flags |= IFF_NOARP; + + return 0; } + static int get_if(struct dvb_net *dvbnet) { int i; @@ -493,6 +496,7 @@ static int get_if(struct dvb_net *dvbnet static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid) { struct net_device *net; + struct dmx_demux *demux; struct dvb_net_priv *priv; int result; int if_num; @@ -500,20 +504,25 @@ static int dvb_net_add_if(struct dvb_net if ((if_num = get_if(dvbnet)) < 0) return -EINVAL; - net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", - dvb_net_setup); - if (!net) - return -ENOMEM; + net = &dvbnet->device[if_num]; + demux = dvbnet->demux; - sprintf(net->name, "dvb%d_%d", dvbnet->dvbdev->adapter->num, if_num); + memset(net, 0, sizeof(struct net_device)); + memcpy(net->name, "dvb0_0", 7); + net->name[3] = dvbnet->dvbdev->adapter->num + '0'; + net->name[5] = if_num + '0'; net->addr_len = 6; memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6); + net->next = NULL; + net->init = dvb_net_init_dev; - dvbnet->device[if_num] = net; + if (!(net->priv = kmalloc(sizeof(struct dvb_net_priv), GFP_KERNEL))) + return -ENOMEM; priv = net->priv; - priv->demux = dvbnet->demux; + memset(priv, 0, sizeof(struct dvb_net_priv)); + priv->demux = demux; priv->pid = pid; priv->rx_mode = RX_MODE_UNI; @@ -523,7 +532,6 @@ static int dvb_net_add_if(struct dvb_net net->base_addr = pid; if ((result = register_netdev(net)) < 0) { - kfree(net); return result; } @@ -533,20 +541,18 @@ static int dvb_net_add_if(struct dvb_net static int dvb_net_remove_if(struct dvb_net *dvbnet, int num) { - struct net_device *net = dvbnet->device[num]; - struct dvb_net_priv *priv = net->priv; + struct dvb_net_priv *priv = dvbnet->device[num].priv; if (!dvbnet->state[num]) return -EINVAL; if (priv->in_use) return -EBUSY; - dvb_net_stop(net); + dvb_net_stop(&dvbnet->device[num]); flush_scheduled_work(); - unregister_netdev(net); + kfree(priv); + unregister_netdev(&dvbnet->device[num]); dvbnet->state[num]=0; - free_netdev(net); - return 0; } diff -prauN linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_net.h wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_net.h --- linux-2.6.0-test7/drivers/media/dvb/dvb-core/dvb_net.h 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/dvb-core/dvb_net.h 2003-10-14 02:49:47.000000000 -0700 @@ -34,7 +34,7 @@ struct dvb_net { struct dvb_device *dvbdev; - struct net_device *device[DVB_NET_DEVICES_MAX]; + struct net_device device[DVB_NET_DEVICES_MAX]; int state[DVB_NET_DEVICES_MAX]; struct dmx_demux *demux; }; diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/Kconfig wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/Kconfig --- linux-2.6.0-test7/drivers/media/dvb/frontends/Kconfig 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -16,16 +16,6 @@ config DVB_STV0299 DVB adapter simply enable all supported frontends, the right one will get autodetected. -config DVB_ALPS_BSRV2 - tristate "Alps BSRV2 (QPSK)" - depends on DVB_CORE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - - If you don't know what tuner module is soldered on your - DVB adapter simply enable all supported frontends, the - right one will get autodetected. - config DVB_SP887X tristate "Frontends with sp887x demodulators, e.g. Microtune DTF7072" depends on DVB_CORE @@ -125,6 +115,16 @@ config DVB_VES1820 DVB adapter simply enable all supported frontends, the right one will get autodetected. +config DVB_VES1X93 + tristate "Frontends with VES1893 or VES1993 demodulator (QPSK)" + depends on DVB_CORE + help + A DVB-S tuner module. Say Y when you want to support this frontend. + + If you don't know what tuner module is soldered on your + DVB adapter simply enable all supported frontends, the + right one will get autodetected. + config DVB_TDA1004X tristate "Frontends with external TDA1004X demodulators (OFDM)" depends on DVB_CORE && !STANDALONE diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/Makefile wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/Makefile --- linux-2.6.0-test7/drivers/media/dvb/frontends/Makefile 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/Makefile 2003-10-14 02:49:47.000000000 -0700 @@ -5,7 +5,6 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ obj-$(CONFIG_DVB_STV0299) += stv0299.o -obj-$(CONFIG_DVB_ALPS_BSRV2) += alps_bsrv2.o obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o @@ -14,5 +13,6 @@ obj-$(CONFIG_DVB_GRUNDIG_29504_491) += g obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o obj-$(CONFIG_DVB_MT312) += mt312.o obj-$(CONFIG_DVB_VES1820) += ves1820.o +obj-$(CONFIG_DVB_VES1X93) += ves1x93.o obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/alps_bsrv2.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_bsrv2.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/alps_bsrv2.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_bsrv2.c 1969-12-31 16:00:00.000000000 -0800 @@ -1,469 +0,0 @@ -/* - Driver for Alps BSRV2 QPSK Frontend - - Copyright (C) 1999 Convergence Integrated Media GmbH - - 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. - -*/ - -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" - -static int debug = 0; -#define dprintk if (debug) printk - - -static struct dvb_frontend_info bsrv2_info = { - .name = "Alps BSRV2", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 250, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, -/* . symbol_rate_tolerance = ???,*/ - .notifier_delay = 50, /* 1/20 s */ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK -}; - - - -static u8 init_1893_tab [] = { - 0x01, 0xA4, 0x35, 0x81, 0x2A, 0x0d, 0x55, 0xC4, - 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7F, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xDC, 0x00, - 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 -}; - - -static u8 init_1893_wtab[] = -{ - 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, - 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, - 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, - 1,1,1,0,1,1 -}; - - -static int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) -{ - u8 buf [] = { 0x00, reg, data }; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; - int err; - - if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - - -static u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) -{ - int ret; - u8 b0 [] = { 0x00, reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 }, - { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c->xfer (i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); - - return b1[0]; -} - - -static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) -{ - int ret; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; - - ret = i2c->xfer (i2c, &msg, 1); - - if (ret != 1) - printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret); - - return (ret != 1) ? -1 : 0; -} - - - -/** - * set up the downconverter frequency divisor for a - * reference clock comparision frequency of 125 kHz. - */ -static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) -{ - u32 div = (freq + 479500) / 125; - u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 }; - - return sp5659_write (i2c, buf); -} - - -static int ves1893_init (struct dvb_i2c_bus *i2c) -{ - int i; - - dprintk("%s: init chip\n", __FUNCTION__); - - for (i=0; i<54; i++) - if (init_1893_wtab[i]) - ves1893_writereg (i2c, i, init_1893_tab[i]); - - return 0; -} - - -static int ves1893_clr_bit (struct dvb_i2c_bus *i2c) -{ - ves1893_writereg (i2c, 0, init_1893_tab[0] & 0xfe); - ves1893_writereg (i2c, 0, init_1893_tab[0]); - ves1893_writereg (i2c, 3, 0x00); - return ves1893_writereg (i2c, 3, init_1893_tab[3]); -} - - -static int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) -{ - u8 val; - - /* - * inversion on/off are interchanged because i and q seem to - * be swapped on the hardware - */ - - switch (inversion) { - case INVERSION_OFF: - val = 0xc0; - break; - case INVERSION_ON: - val = 0x80; - break; - case INVERSION_AUTO: - val = 0x00; - break; - default: - return -EINVAL; - } - - /* needs to be saved for FE_GET_FRONTEND */ - init_1893_tab[0x0c] = (init_1893_tab[0x0c] & 0x3f) | val; - - return ves1893_writereg (i2c, 0x0c, init_1893_tab[0x0c]); -} - - -static int ves1893_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) -{ - if (fec == FEC_AUTO) - return ves1893_writereg (i2c, 0x0d, 0x08); - else if (fec < FEC_1_2 || fec > FEC_8_9) - return -EINVAL; - else - return ves1893_writereg (i2c, 0x0d, fec - FEC_1_2); -} - - -static fe_code_rate_t ves1893_get_fec (struct dvb_i2c_bus *i2c) -{ - return FEC_1_2 + ((ves1893_readreg (i2c, 0x0d) >> 4) & 0x7); -} - - -static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) -{ - u32 BDR; - u32 ratio; - u8 ADCONF, FCONF, FNR; - u32 BDRI; - u32 tmp; - - dprintk("%s: srate == %ud\n", __FUNCTION__, (unsigned int) srate); - - if (srate > 90100000UL/2) - srate = 90100000UL/2; - - if (srate < 500000) - srate = 500000; - -#define MUL (1UL<<26) -#define FIN (90106000UL>>4) - - tmp = srate << 6; - ratio = tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - FNR = 0xff; - - if (ratio < MUL/3) FNR = 0; - if (ratio < (MUL*11)/50) FNR = 1; - if (ratio < MUL/6) FNR = 2; - if (ratio < MUL/9) FNR = 3; - if (ratio < MUL/12) FNR = 4; - if (ratio < (MUL*11)/200) FNR = 5; - if (ratio < MUL/24) FNR = 6; - if (ratio < (MUL*27)/1000) FNR = 7; - if (ratio < MUL/48) FNR = 8; - if (ratio < (MUL*137)/10000) FNR = 9; - - if (FNR == 0xff) { - ADCONF = 0x89; - FCONF = 0x80; - FNR = 0; - } else { - ADCONF = 0x81; - FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); - } - - BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; - BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; - - dprintk("FNR= %d\n", FNR); - dprintk("ratio= %08x\n", (unsigned int) ratio); - dprintk("BDR= %08x\n", (unsigned int) BDR); - dprintk("BDRI= %02x\n", (unsigned int) BDRI); - - if (BDRI > 0xff) - BDRI = 0xff; - - ves1893_writereg (i2c, 0x06, 0xff & BDR); - ves1893_writereg (i2c, 0x07, 0xff & (BDR >> 8)); - ves1893_writereg (i2c, 0x08, 0x0f & (BDR >> 16)); - - ves1893_writereg (i2c, 0x09, BDRI); - ves1893_writereg (i2c, 0x20, ADCONF); - ves1893_writereg (i2c, 0x21, FCONF); - - if (srate < 6000000) - ves1893_writereg (i2c, 0x05, init_1893_tab[0x05] | 0x80); - else - ves1893_writereg (i2c, 0x05, init_1893_tab[0x05] & 0x7f); - - ves1893_writereg (i2c, 0x00, 0x00); - ves1893_writereg (i2c, 0x00, 0x01); - - ves1893_clr_bit (i2c); - - return 0; -} - - -static int ves1893_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) -{ - switch (voltage) { - case SEC_VOLTAGE_13: - return ves1893_writereg (i2c, 0x1f, 0x20); - case SEC_VOLTAGE_18: - return ves1893_writereg (i2c, 0x1f, 0x30); - case SEC_VOLTAGE_OFF: - return ves1893_writereg (i2c, 0x1f, 0x00); - default: - return -EINVAL; - } -} - - -static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) -{ - struct dvb_i2c_bus *i2c = fe->i2c; - - switch (cmd) { - case FE_GET_INFO: - memcpy (arg, &bsrv2_info, sizeof(struct dvb_frontend_info)); - break; - - case FE_READ_STATUS: - { - fe_status_t *status = arg; - u8 sync = ves1893_readreg (i2c, 0x0e); - - *status = 0; - - if (sync & 1) - *status |= FE_HAS_SIGNAL; - - if (sync & 2) - *status |= FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_SYNC; - - if ((sync & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - break; - } - - case FE_READ_BER: - { - u32 *ber = (u32 *) arg; - - *ber = ves1893_readreg (i2c, 0x15); - *ber |= (ves1893_readreg (i2c, 0x16) << 8); - *ber |= ((ves1893_readreg (i2c, 0x17) & 0x0f) << 16); - *ber *= 10; - break; - } - - case FE_READ_SIGNAL_STRENGTH: - { - u8 signal = ~ves1893_readreg (i2c, 0x0b); - *((u16*) arg) = (signal << 8) | signal; - break; - } - - case FE_READ_SNR: - { - u8 snr = ~ves1893_readreg (i2c, 0x1c); - *(u16*) arg = (snr << 8) | snr; - break; - } - - case FE_READ_UNCORRECTED_BLOCKS: - { - *(u32*) arg = ves1893_readreg (i2c, 0x18) & 0x7f; - - if (*(u32*) arg == 0x7f) - *(u32*) arg = 0xffffffff; /* counter overflow... */ - - ves1893_writereg (i2c, 0x18, 0x00); /* reset the counter */ - ves1893_writereg (i2c, 0x18, 0x80); /* dto. */ - break; - } - - case FE_SET_FRONTEND: - { - struct dvb_frontend_parameters *p = arg; - - sp5659_set_tv_freq (i2c, p->frequency, 0); - ves1893_set_inversion (i2c, p->inversion); - ves1893_set_fec (i2c, p->u.qpsk.fec_inner); -// sp5659_set_tv_freq (i2c, p->frequency, 0); - ves1893_set_symbolrate (i2c, p->u.qpsk.symbol_rate); - break; - } - - case FE_GET_FRONTEND: - { - struct dvb_frontend_parameters *p = arg; - int afc; - - afc = ((int)((char)(ves1893_readreg (i2c, 0x0a) << 1)))/2; - afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; - - p->frequency -= afc; - - /* - * inversion indicator is only valid - * if auto inversion was used - */ - if (!(init_1893_tab[0x0c] & 0x80)) - p->inversion = (ves1893_readreg (i2c, 0x0f) & 2) ? - INVERSION_OFF : INVERSION_ON; - p->u.qpsk.fec_inner = ves1893_get_fec (i2c); - /* XXX FIXME: timing offset !! */ - break; - } - - case FE_SLEEP: - ves1893_writereg (i2c, 0x1f, 0x00); /* LNB power off */ - return ves1893_writereg (i2c, 0x00, 0x08); - - case FE_INIT: - return ves1893_init (i2c); - - case FE_RESET: - return ves1893_clr_bit (i2c); - - case FE_SET_TONE: - return -EOPNOTSUPP; /* the ves1893 can generate the 22k */ - /* let's implement this when we have */ - /* a box that uses the 22K_0 pin... */ - case FE_SET_VOLTAGE: - return ves1893_set_voltage (i2c, (fe_sec_voltage_t) arg); - - default: - return -EOPNOTSUPP; - }; - - return 0; -} - - -static int bsrv2_attach (struct dvb_i2c_bus *i2c) -{ - if ((ves1893_readreg (i2c, 0x1e) & 0xf0) != 0xd0) - return -ENODEV; - - dvb_register_frontend (bsrv2_ioctl, i2c, NULL, &bsrv2_info); - - return 0; -} - - -static void bsrv2_detach (struct dvb_i2c_bus *i2c) -{ - dvb_unregister_frontend (bsrv2_ioctl, i2c); -} - - -static int __init init_bsrv2 (void) -{ - return dvb_register_i2c_device (THIS_MODULE, bsrv2_attach, bsrv2_detach); -} - - -static void __exit exit_bsrv2 (void) -{ - dvb_unregister_i2c_device (bsrv2_attach); -} - - -module_init(init_bsrv2); -module_exit(exit_bsrv2); - - -MODULE_DESCRIPTION("BSRV2 DVB-S Frontend"); -MODULE_AUTHOR("Ralph Metzler"); -MODULE_LICENSE("GPL"); -MODULE_PARM(debug,"i"); - diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/alps_tdlb7.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_tdlb7.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/alps_tdlb7.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_tdlb7.c 2003-10-14 02:49:47.000000000 -0700 @@ -1,7 +1,7 @@ /* Driver for Alps TDLB7 Frontend - Copyright (C) 1999 Juergen Peitz + Copyright (C) 1999 Juergen Peitz 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 @@ -22,23 +22,9 @@ /* - - Wrote this code mainly to get my own card running. It's working for me, but I - hope somebody who knows more about linux programming and the DVB driver can - improve it. - - Reused a lot from the existing driver and tuner code. - Thanks to everybody who worked on it! - - This driver needs a copy of the microcode file 'Sc_main.mc' from the Haupauge - windows driver in the 'usr/lib/DVB/driver/frontends' directory. - You can also pass the complete file name with the module parameter 'mcfile'. - - The code only needs to be loaded once after a power on. Because loading the - microcode to the card takes some time, you can use the 'loadcode=0' module - parameter, if you only want to reload the dvb driver. - - Juergen Peitz + This driver needs a copy of the firmware file 'Sc_main.mc' from the Haupauge + windows driver in the '/usr/lib/DVB/driver/frontends' directory. + You can also pass the complete file name with the module parameter 'firmware_file'. */ @@ -50,49 +36,46 @@ #include #include #include +#include #include "dvb_frontend.h" +#include "dvb_functions.h" -static int debug = 0; - -static int loadcode = 1; +#ifndef CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION +#define CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION "/usr/lib/DVB/driver/frontends/Sc_main.mc" +#endif -static char * mcfile = "/usr/lib/DVB/driver/frontends/Sc_main.mc"; +static char * firmware_file = CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION; +static int debug = 0; #define dprintk if (debug) printk -/* microcode size for sp8870 */ -#define SP8870_CODE_SIZE 16382 +/* firmware size for sp8870 */ +#define SP8870_FIRMWARE_SIZE 16382 -/* starting point for microcode in file 'Sc_main.mc' */ -#define SP8870_CODE_OFFSET 0x0A +/* starting point for firmware in file 'Sc_main.mc' */ +#define SP8870_FIRMWARE_OFFSET 0x0A static int errno; static struct dvb_frontend_info tdlb7_info = { - .name = "Alps TDLB7", - .type = FE_OFDM, - .frequency_min = 470000000, - .frequency_max = 860000000, - .frequency_stepsize = 166666, -#if 0 - .frequency_tolerance = ???, - .symbol_rate_min = ???, - .symbol_rate_max = ???, - .symbol_rate_tolerance = ???, - .notifier_delay = 0, -#endif - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + name: "Alps TDLB7", + type: FE_OFDM, + frequency_min: 470000000, + frequency_max: 860000000, + frequency_stepsize: 166666, + caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER }; static int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data) { u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = buf, .len = 4 }; + struct i2c_msg msg = { addr: 0x71, flags: 0, buf: buf, len: 4 }; int err; if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { @@ -109,13 +92,15 @@ static u16 sp8870_readreg (struct dvb_i2 int ret; u8 b0 [] = { reg >> 8 , reg & 0xff }; u8 b1 [] = { 0, 0 }; - struct i2c_msg msg [] = { { .addr = 0x71, .flags = 0, .buf = b0, .len = 2 }, - { .addr = 0x71, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; + struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 }, + { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } }; ret = i2c->xfer (i2c, msg, 2); - if (ret != 2) + if (ret != 2) { dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + return -1; + } return (b1[0] << 8 | b1[1]); } @@ -124,7 +109,7 @@ static u16 sp8870_readreg (struct dvb_i2 static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = 4 }; + struct i2c_msg msg = { addr: 0x60, flags: 0, buf: data, len: 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -135,7 +120,7 @@ static int sp5659_write (struct dvb_i2c_ } -static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static void sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) { u32 div = (freq + 36200000) / 166666; u8 buf [4]; @@ -151,102 +136,146 @@ static int sp5659_set_tv_freq (struct dv buf[2] = 0x85; buf[3] = pwr << 6; - return sp5659_write (i2c, buf); + /* open i2c gate for PLL message transmission... */ + sp8870_writereg(i2c, 0x206, 0x001); + sp5659_write (i2c, buf); + sp8870_writereg(i2c, 0x206, 0x000); } -static int sp8870_read_code(const char *fn, char **fp) +static int sp8870_read_firmware_file (const char *fn, char **fp) { int fd; - loff_t l; + loff_t filesize; char *dp; fd = open(fn, 0, 0); if (fd == -1) { - printk(KERN_INFO "%s: Unable to load '%s'.\n", __FUNCTION__, fn); - return -1; + printk("%s: unable to open '%s'.\n", __FUNCTION__, fn); + return -EIO; } - l = lseek(fd, 0L, 2); - if (l <= 0 || l < SP8870_CODE_OFFSET+SP8870_CODE_SIZE) { - printk(KERN_INFO "%s: code file too small '%s'\n", __FUNCTION__, fn); + + filesize = lseek(fd, 0L, 2); + if (filesize <= 0 || filesize < SP8870_FIRMWARE_OFFSET + SP8870_FIRMWARE_SIZE) { + printk("%s: firmware filesize to small '%s'\n", __FUNCTION__, fn); sys_close(fd); - return -1; + return -EIO; } - lseek(fd, SP8870_CODE_OFFSET, 0); - *fp= dp = vmalloc(SP8870_CODE_SIZE); + + *fp= dp = vmalloc(SP8870_FIRMWARE_SIZE); if (dp == NULL) { - printk(KERN_INFO "%s: Out of memory loading '%s'.\n", __FUNCTION__, fn); + printk("%s: out of memory loading '%s'.\n", __FUNCTION__, fn); sys_close(fd); - return -1; + return -EIO; } - if (read(fd, dp, SP8870_CODE_SIZE) != SP8870_CODE_SIZE) { - printk(KERN_INFO "%s: Failed to read '%s'.\n",__FUNCTION__, fn); + + lseek(fd, SP8870_FIRMWARE_OFFSET, 0); + if (read(fd, dp, SP8870_FIRMWARE_SIZE) != SP8870_FIRMWARE_SIZE) { + printk("%s: failed to read '%s'.\n",__FUNCTION__, fn); vfree(dp); sys_close(fd); - return -1; + return -EIO; } + sys_close(fd); *fp = dp; + return 0; } -static int sp8870_load_code(struct dvb_i2c_bus *i2c) +static int sp8870_firmware_upload (struct dvb_i2c_bus *i2c) { - /* this takes a long time. is there a way to do it faster? */ - char *lcode; struct i2c_msg msg; - unsigned char buf[255]; - int err; - int p=0; - int c; + char *fw_buf = NULL; + int fw_pos; + u8 tx_buf[255]; + int tx_len; + int err = 0; mm_segment_t fs = get_fs(); + dprintk ("%s: ...\n", __FUNCTION__); + // system controller stop sp8870_writereg(i2c,0x0F00,0x0000); // instruction RAM register hiword - sp8870_writereg(i2c,0x8F08,((SP8870_CODE_SIZE/2) & 0xFFFF)); + sp8870_writereg(i2c, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF)); // instruction RAM MWR - sp8870_writereg(i2c,0x8F0A,((SP8870_CODE_SIZE/2) >> 16)); + sp8870_writereg(i2c, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16)); + // reading firmware file to buffer set_fs(get_ds()); - if (sp8870_read_code(mcfile,(char**) &lcode)<0) return -1; + err = sp8870_read_firmware_file(firmware_file, (char**) &fw_buf); set_fs(fs); - while (pxfer (i2c, &msg, 1)) != 1) { - dprintk ("%s: i2c error (err == %i)\n", - __FUNCTION__, err); - vfree(lcode); - return -EREMOTEIO; + printk("%s: firmware upload failed!\n", __FUNCTION__); + printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err); + vfree(fw_buf); + return err; } - - p+=252; + fw_pos += tx_len; } - vfree(lcode); + + vfree(fw_buf); + + dprintk ("%s: done!\n", __FUNCTION__); return 0; }; -static int sp8870_init (struct dvb_i2c_bus *i2c) +static void sp8870_microcontroller_stop (struct dvb_i2c_bus *i2c) +{ + sp8870_writereg(i2c, 0x0F08, 0x000); + sp8870_writereg(i2c, 0x0F09, 0x000); + + // microcontroller STOP + sp8870_writereg(i2c, 0x0F00, 0x000); +} + + +static void sp8870_microcontroller_start (struct dvb_i2c_bus *i2c) { + sp8870_writereg(i2c, 0x0F08, 0x000); + sp8870_writereg(i2c, 0x0F09, 0x000); + + // microcontroller START + sp8870_writereg(i2c, 0x0F00, 0x001); + // not documented but if we don't read 0x0D01 out here + // we don't get a correct data valid signal + sp8870_readreg(i2c, 0x0D01); +} + +static int sp8870_init (struct dvb_i2c_bus *i2c) +{ dprintk ("%s\n", __FUNCTION__); + /* enable TS output and interface pins */ + sp8870_writereg(i2c, 0xc18, 0x00d); + // system controller stop - sp8870_writereg(i2c,0x0F00,0x0000); + sp8870_microcontroller_stop(i2c); - // ADC mode: 2 for MT8872, 3 for MT8870/8871 + // ADC mode sp8870_writereg(i2c,0x0301,0x0003); // Reed Solomon parity bytes passed to output @@ -255,103 +284,214 @@ static int sp8870_init (struct dvb_i2c_b // MPEG clock is suppressed if no valid data sp8870_writereg(i2c,0x0C14,0x0001); - // sample rate correction bit [23..17] - sp8870_writereg(i2c,0x0319,0x000A); + /* bit 0x010: enable data valid signal */ + sp8870_writereg(i2c, 0x0D00, 0x010); + sp8870_writereg(i2c, 0x0D01, 0x000); - // sample rate correction bit [16..0] - sp8870_writereg(i2c,0x031A,0x0AAB); + return 0; +} - // integer carrier offset - sp8870_writereg(i2c,0x0309,0x0400); - // fractional carrier offset - sp8870_writereg(i2c,0x030A,0x0000); +static int sp8870_read_status (struct dvb_i2c_bus *i2c, fe_status_t * fe_status) +{ + int status; + int signal; - // filter for 8 Mhz channel - sp8870_writereg(i2c,0x0311,0x0000); + *fe_status = 0; - // scan order: 2k first = 0x0000, 8k first = 0x0001 - sp8870_writereg(i2c,0x0338,0x0000); + status = sp8870_readreg (i2c, 0x0200); + if (status < 0) + return -EIO; + + signal = sp8870_readreg (i2c, 0x0303); + if (signal < 0) + return -EIO; + + if (signal > 0x0F) + *fe_status |= FE_HAS_SIGNAL; + if (status & 0x08) + *fe_status |= FE_HAS_SYNC; + if (status & 0x04) + *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI; return 0; } -static int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int sp8870_read_ber (struct dvb_i2c_bus *i2c, u32 * ber) { - struct dvb_i2c_bus *i2c = fe->i2c; + int ret; + u32 tmp; - switch (cmd) { - case FE_GET_INFO: - memcpy (arg, &tdlb7_info, sizeof(struct dvb_frontend_info)); - break; + *ber = 0; - case FE_READ_STATUS: - { - fe_status_t *status = arg; - int sync = sp8870_readreg (i2c, 0x0200); - int signal = 0xff-sp8870_readreg (i2c, 0x303); + ret = sp8870_readreg(i2c, 0xC08); + if (ret < 0) + return -EIO; - *status=0; - if (signal>10) // FIXME: is 10 the right value ? - *status |= FE_HAS_SIGNAL; + tmp = ret & 0x3F; - if (sync&0x04) // FIXME: find criteria - *status |= FE_HAS_CARRIER; + ret = sp8870_readreg(i2c, 0xC07); + if (ret < 0) + return -EIO; - if (sync&0x04) // FIXME - *status |= FE_HAS_VITERBI; + tmp = ret << 6; - if (sync&0x08) // FIXME - *status |= FE_HAS_SYNC; + if (tmp >= 0x3FFF0) + tmp = ~0; - if (sync&0x04) - *status |= FE_HAS_LOCK; - break; + *ber = tmp; + return 0; } - case FE_READ_BER: + +static int sp8870_read_signal_strength (struct dvb_i2c_bus *i2c, u16 * signal) { - u32 *ber=(u32 *) arg; - // bit error rate before Viterbi - *ber=sp8870_readreg(i2c,0x0C07); - break; + int ret; + u16 tmp; - } + *signal = 0; - case FE_READ_SIGNAL_STRENGTH: // FIXME: correct registers ? - { - *((u16*) arg) = 0xffff-((sp8870_readreg (i2c, 0x306) << 8) | sp8870_readreg (i2c, 0x303)); - break; + ret = sp8870_readreg (i2c, 0x306); + if (ret < 0) + return -EIO; + + tmp = ret << 8; + + ret = sp8870_readreg (i2c, 0x303); + if (ret < 0) + return -EIO; + + tmp |= ret; + + if (tmp) + *signal = 0xFFFF - tmp; + + return 0; } - case FE_READ_SNR: // not supported by hardware? + +static int sp8870_read_snr(struct dvb_i2c_bus *i2c, u32* snr) { - s32 *snr=(s32 *) arg; *snr=0; return -EOPNOTSUPP; } - case FE_READ_UNCORRECTED_BLOCKS: // not supported by hardware? + +static int sp8870_read_uncorrected_blocks (struct dvb_i2c_bus *i2c, u32* ublocks) { - u32 *ublocks=(u32 *) arg; + int ret; + *ublocks=0; - return -EOPNOTSUPP; + + ret = sp8870_readreg(i2c, 0xC0C); + if (ret < 0) + return -EIO; + + if (ret == 0xFFFF) + ret = ~0; + + *ublocks = ret; + + return 0; } - case FE_SET_FRONTEND: + +static int sp8870_read_data_valid_signal(struct dvb_i2c_bus *i2c) +{ + return (sp8870_readreg(i2c, 0x0D02) > 0); +} + + +static +int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) +{ + int known_parameters = 1; + + *reg0xc05 = 0x000; + + switch (p->u.ofdm.constellation) { + case QPSK: + break; + case QAM_16: + *reg0xc05 |= (1 << 10); + break; + case QAM_64: + *reg0xc05 |= (2 << 10); + break; + case QAM_AUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + switch (p->u.ofdm.hierarchy_information) { + case HIERARCHY_NONE: + break; + case HIERARCHY_1: + *reg0xc05 |= (1 << 7); + break; + case HIERARCHY_2: + *reg0xc05 |= (2 << 7); + break; + case HIERARCHY_4: + *reg0xc05 |= (3 << 7); + break; + case HIERARCHY_AUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + switch (p->u.ofdm.code_rate_HP) { + case FEC_1_2: + break; + case FEC_2_3: + *reg0xc05 |= (1 << 3); + break; + case FEC_3_4: + *reg0xc05 |= (2 << 3); + break; + case FEC_5_6: + *reg0xc05 |= (3 << 3); + break; + case FEC_7_8: + *reg0xc05 |= (4 << 3); + break; + case FEC_AUTO: + known_parameters = 0; + break; + default: + return -EINVAL; + }; + + if (known_parameters) + *reg0xc05 |= (2 << 1); /* use specified parameters */ + else + *reg0xc05 |= (1 << 1); /* enable autoprobing */ + + return 0; +} + + +static int sp8870_set_frontend_parameters (struct dvb_i2c_bus *i2c, + struct dvb_frontend_parameters *p) { - struct dvb_frontend_parameters *p = arg; + int err; + u16 reg0xc05; + + if ((err = configure_reg0xc05(p, ®0xc05))) + return err; // system controller stop - sp8870_writereg(i2c,0x0F00,0x0000); + sp8870_microcontroller_stop(i2c); + // set tuner parameters sp5659_set_tv_freq (i2c, p->frequency); - // read status reg in order to clear pending irqs - sp8870_readreg(i2c, 0x200); - // sample rate correction bit [23..17] sp8870_writereg(i2c,0x0319,0x000A); @@ -378,28 +518,141 @@ static int tdlb7_ioctl (struct dvb_front else sp8870_writereg(i2c,0x0338,0x0001); - // instruction RAM register loword - sp8870_writereg(i2c,0x0F09,0x0000); + sp8870_writereg(i2c, 0xc05, reg0xc05); - // instruction RAM register hiword - sp8870_writereg(i2c,0x0F08,0x0000); + // read status reg in order to clear pending irqs + sp8870_readreg(i2c, 0x200); // system controller start - sp8870_writereg(i2c,0x0F00,0x0001); + sp8870_microcontroller_start(i2c); - break; + return 0; } - case FE_GET_FRONTEND: // FIXME: read known values back from Hardware... + +// number of trials to recover from lockup +#define MAXTRIALS 5 +// maximum checks for data valid signal +#define MAXCHECKS 100 + +// only for debugging: counter for detected lockups +static int lockups = 0; +// only for debugging: counter for channel switches +static int switches = 0; + +static int sp8870_set_frontend (struct dvb_i2c_bus *i2c, struct dvb_frontend_parameters *p) { + /* + The firmware of the sp8870 sometimes locks up after setting frontend parameters. + We try to detect this by checking the data valid signal. + If it is not set after MAXCHECKS we try to recover the lockup by setting + the frontend parameters again. + */ + + int err = 0; + int valid = 0; + int trials = 0; + int check_count = 0; + + dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency); + + for (trials = 1; trials <= MAXTRIALS; trials++) { + + if ((err = sp8870_set_frontend_parameters(i2c, p))) + return err; + + for (check_count = 0; check_count < MAXCHECKS; check_count++) { +// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0); + valid = sp8870_read_data_valid_signal(i2c); + if (valid) { + dprintk("%s: delay = %i usec\n", + __FUNCTION__, check_count * 10); + break; + } + udelay(10); + } + if (valid) break; } - case FE_SLEEP: // is this supported by hardware? + if (!valid) { + printk("%s: firmware crash!!!!!!\n", __FUNCTION__); + return -EIO; + } + + if (debug) { + if (valid) { + if (trials > 1) { + printk("%s: firmware lockup!!!\n", __FUNCTION__); + printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1); + lockups++; + } + } + switches++; + printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups); + } + + return 0; +} + + +static int sp8870_sleep(struct dvb_i2c_bus *i2c) +{ + // tristate TS output and disable interface pins + return sp8870_writereg(i2c, 0xC18, 0x000); +} + + +static int sp8870_wake_up(struct dvb_i2c_bus *i2c) +{ + // enable TS output and interface pins + return sp8870_writereg(i2c, 0xC18, 0x00D); +} + + +static int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +{ + struct dvb_i2c_bus *i2c = fe->i2c; + + switch (cmd) { + case FE_GET_INFO: + memcpy (arg, &tdlb7_info, sizeof(struct dvb_frontend_info)); + break; + + case FE_READ_STATUS: + return sp8870_read_status(i2c, (fe_status_t *) arg); + + case FE_READ_BER: + return sp8870_read_ber(i2c, (u32 *) arg); + + case FE_READ_SIGNAL_STRENGTH: + return sp8870_read_signal_strength(i2c, (u16 *) arg); + + case FE_READ_SNR: // not supported by hardware? + return sp8870_read_snr(i2c, (u32 *) arg); + + case FE_READ_UNCORRECTED_BLOCKS: + return sp8870_read_uncorrected_blocks(i2c, (u32 *) arg); + + case FE_SET_FRONTEND: + return sp8870_set_frontend(i2c, (struct dvb_frontend_parameters*) arg); + + case FE_RESET: return -EOPNOTSUPP; + case FE_GET_FRONTEND: // FIXME: read known values back from Hardware... + return -EOPNOTSUPP; + + case FE_SLEEP: + return sp8870_sleep(i2c); + case FE_INIT: - return sp8870_init (i2c); + sp8870_wake_up(i2c); + if (fe->data == NULL) { // first time initialisation... + fe->data = (void*) ~0; + sp8870_init (i2c); + } + break; default: return -EOPNOTSUPP; @@ -409,31 +662,22 @@ static int tdlb7_ioctl (struct dvb_front } -static int tdlb7_attach (struct dvb_i2c_bus *i2c) +static int tdlb7_attach (struct dvb_i2c_bus *i2c, void **data) { - - struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = NULL, .len = 0 }; + struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 }; dprintk ("%s\n", __FUNCTION__); if (i2c->xfer (i2c, &msg, 1) != 1) return -ENODEV; - if (loadcode) { - dprintk("%s: loading mcfile '%s' !\n", __FUNCTION__, mcfile); - if (sp8870_load_code(i2c)==0) - dprintk("%s: microcode loaded!\n", __FUNCTION__); - }else{ - dprintk("%s: without loading mcfile!\n", __FUNCTION__); - } - - dvb_register_frontend (tdlb7_ioctl, i2c, NULL, &tdlb7_info); + sp8870_firmware_upload(i2c); - return 0; + return dvb_register_frontend (tdlb7_ioctl, i2c, NULL, &tdlb7_info); } -static void tdlb7_detach (struct dvb_i2c_bus *i2c) +static void tdlb7_detach (struct dvb_i2c_bus *i2c, void *data) { dprintk ("%s\n", __FUNCTION__); @@ -464,11 +708,8 @@ module_exit(exit_tdlb7); MODULE_PARM(debug,"i"); MODULE_PARM_DESC(debug, "enable verbose debug messages"); -MODULE_PARM(loadcode,"i"); -MODULE_PARM_DESC(loadcode, "load tuner microcode"); - -MODULE_PARM(mcfile,"s"); -MODULE_PARM_DESC(mcfile, "where to find the microcode file"); +MODULE_PARM(firmware_file,"s"); +MODULE_PARM_DESC(firmware_file, "where to find the firmware file"); MODULE_DESCRIPTION("TDLB7 DVB-T Frontend"); MODULE_AUTHOR("Juergen Peitz"); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/alps_tdmb7.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_tdmb7.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/alps_tdmb7.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/alps_tdmb7.c 2003-10-14 02:49:47.000000000 -0700 @@ -402,7 +402,7 @@ static int tdmb7_ioctl (struct dvb_front -static int tdmb7_attach (struct dvb_i2c_bus *i2c) +static int tdmb7_attach (struct dvb_i2c_bus *i2c, void **data) { struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = NULL,. len = 0 }; @@ -411,13 +411,11 @@ static int tdmb7_attach (struct dvb_i2c_ if (i2c->xfer (i2c, &msg, 1) != 1) return -ENODEV; - dvb_register_frontend (tdmb7_ioctl, i2c, NULL, &tdmb7_info); - - return 0; + return dvb_register_frontend (tdmb7_ioctl, i2c, NULL, &tdmb7_info); } -static void tdmb7_detach (struct dvb_i2c_bus *i2c) +static void tdmb7_detach (struct dvb_i2c_bus *i2c, void *data) { dprintk ("%s\n", __FUNCTION__); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/at76c651.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/at76c651.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/at76c651.c 2003-10-08 12:24:42.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/at76c651.c 2003-10-14 02:49:47.000000000 -0700 @@ -37,6 +37,8 @@ #include "dvb_functions.h" static int debug = 0; +static u8 at76c651_qam; +static u8 at76c651_revision; #define dprintk if (debug) printk @@ -53,7 +55,7 @@ static int debug = 0; static struct dvb_frontend_info at76c651_info = { - .name = "Atmel AT76c651(B) with DAT7021", + .name = "Atmel AT76C651(B) with DAT7021", .type = FE_QAM, .frequency_min = 48250000, .frequency_max = 863250000, @@ -126,46 +128,70 @@ static u8 at76c651_readreg(struct dvb_i2 } +static int at76c651_reset(struct dvb_i2c_bus *i2c) +{ + + return at76c651_writereg(i2c, 0x07, 0x01); + +} + +static int at76c651_disable_interrupts(struct dvb_i2c_bus *i2c) +{ + + return at76c651_writereg(i2c, 0x0b, 0x00); + +} + static int at76c651_set_auto_config(struct dvb_i2c_bus *i2c) { + /* + * Autoconfig + */ + at76c651_writereg(i2c, 0x06, 0x01); /* - * performance optimizations + * Performance optimizations, should be done after autoconfig */ at76c651_writereg(i2c, 0x10, 0x06); - at76c651_writereg(i2c, 0x11, 0x10); + at76c651_writereg(i2c, 0x11, ((at76c651_qam == 5) || (at76c651_qam == 7)) ? 0x12 : 0x10); at76c651_writereg(i2c, 0x15, 0x28); at76c651_writereg(i2c, 0x20, 0x09); - at76c651_writereg(i2c, 0x24, 0x90); + at76c651_writereg(i2c, 0x24, ((at76c651_qam == 5) || (at76c651_qam == 7)) ? 0xC0 : 0x90); + at76c651_writereg(i2c, 0x30, 0x90); + if (at76c651_qam == 5) + at76c651_writereg(i2c, 0x35, 0x2A); - return 0; + /* + * Initialize A/D-converter + */ + if (at76c651_revision == 0x11) { + at76c651_writereg(i2c, 0x2E, 0x38); + at76c651_writereg(i2c, 0x2F, 0x13); } -static int at76c651_set_bbfreq(struct dvb_i2c_bus *i2c) -{ + at76c651_disable_interrupts(i2c); - at76c651_writereg(i2c, 0x04, 0x3f); - at76c651_writereg(i2c, 0x05, 0xee); + /* + * Restart operation + */ + + at76c651_reset(i2c); return 0; } -static int at76c651_reset(struct dvb_i2c_bus *i2c) +static int at76c651_set_bbfreq(struct dvb_i2c_bus *i2c) { - return at76c651_writereg(i2c, 0x07, 0x01); - -} - -static int at76c651_disable_interrupts(struct dvb_i2c_bus *i2c) -{ + at76c651_writereg(i2c, 0x04, 0x3f); + at76c651_writereg(i2c, 0x05, 0xee); - return at76c651_writereg(i2c, 0x0b, 0x00); + return 0; } @@ -186,6 +212,10 @@ static int dat7021_write(struct dvb_i2c_ struct i2c_msg msg = { .addr = 0xc2 >> 1, .flags = 0, .buf = (u8 *) & tw, .len = sizeof (tw) }; +#ifdef __LITTLE_ENDIAN + tw = __cpu_to_be32(tw); +#endif + at76c651_switch_tuner_i2c(i2c, 1); ret = i2c->xfer(i2c, &msg, 1); @@ -236,7 +266,7 @@ static int at76c651_set_symbolrate(struc u32 mantissa; if (symbolrate > 9360000) - return -1; + return -EINVAL; /* * FREF = 57800 kHz @@ -258,34 +288,31 @@ static int at76c651_set_symbolrate(struc static int at76c651_set_qam(struct dvb_i2c_bus *i2c, fe_modulation_t qam) { - u8 qamsel = 0; - switch (qam) { - case QPSK: - qamsel = 0x02; + at76c651_qam = 0x02; break; case QAM_16: - qamsel = 0x04; + at76c651_qam = 0x04; break; case QAM_32: - qamsel = 0x05; + at76c651_qam = 0x05; break; case QAM_64: - qamsel = 0x06; + at76c651_qam = 0x06; break; case QAM_128: - qamsel = 0x07; + at76c651_qam = 0x07; break; case QAM_256: - qamsel = 0x08; + at76c651_qam = 0x08; break; #if 0 case QAM_512: - qamsel = 0x09; + at76c651_qam = 0x09; break; case QAM_1024: - qamsel = 0x0A; + at76c651_qam = 0x0A; break; #endif default: @@ -293,7 +320,7 @@ static int at76c651_set_qam(struct dvb_i } - return at76c651_writereg(i2c, 0x03, qamsel); + return at76c651_writereg(i2c, 0x03, at76c651_qam); } @@ -345,7 +372,6 @@ static int at76c651_set_defaults(struct at76c651_set_qam(i2c, QAM_64); at76c651_set_bbfreq(i2c); at76c651_set_auto_config(i2c); - at76c651_disable_interrupts(i2c); return 0; @@ -408,13 +434,12 @@ static int at76c651_ioctl(struct dvb_fro { u8 gain = ~at76c651_readreg(fe->i2c, 0x91); - *(s32 *) arg = (gain << 8) | gain; - *(s32 *) arg = 0x0FFF; + *(u16 *) arg = (gain << 8) | gain; break; } case FE_READ_SNR: - *(s32 *) arg = + *(u16 *) arg = 0xFFFF - ((at76c651_readreg(fe->i2c, 0x8F) << 8) | at76c651_readreg(fe->i2c, 0x90)); @@ -440,59 +465,44 @@ static int at76c651_ioctl(struct dvb_fro return at76c651_reset(fe->i2c); default: - return -ENOSYS; + return -ENOIOCTLCMD; } return 0; } -static int at76c651_attach(struct dvb_i2c_bus *i2c) +static int at76c651_attach(struct dvb_i2c_bus *i2c, void **data) +{ + if ( (at76c651_readreg(i2c, 0x0E) != 0x65) || + ( ( (at76c651_revision = at76c651_readreg(i2c, 0x0F)) & 0xFE) != 0x10) ) { - - if (at76c651_readreg(i2c, 0x0e) != 0x65) { - dprintk("no AT76C651(B) found\n"); - return -ENODEV; - } - if (at76c651_readreg(i2c, 0x0F) != 0x10) { - - if (at76c651_readreg(i2c, 0x0F) == 0x11) { - - dprintk("AT76C651B found\n"); - - } else { - - dprintk("no AT76C651(B) found\n"); - - return -ENODEV; - + if (at76c651_revision == 0x10) + { + dprintk("AT76C651A found\n"); + strcpy(at76c651_info.name,"Atmel AT76C651A with DAT7021"); } - - } else { - + else + { + strcpy(at76c651_info.name,"Atmel AT76C651B with DAT7021"); dprintk("AT76C651B found\n"); - } at76c651_set_defaults(i2c); - dvb_register_frontend(at76c651_ioctl, i2c, NULL, &at76c651_info); - - return 0; + return dvb_register_frontend(at76c651_ioctl, i2c, NULL, &at76c651_info); } -static void at76c651_detach(struct dvb_i2c_bus *i2c) +static void at76c651_detach(struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend(at76c651_ioctl, i2c); - at76c651_disable_interrupts(i2c); - } static int __init at76c651_init(void) @@ -513,11 +523,7 @@ static void __exit at76c651_exit(void) module_init(at76c651_init); module_exit(at76c651_exit); -#ifdef MODULE MODULE_DESCRIPTION("at76c651/dat7021 dvb-c frontend driver"); MODULE_AUTHOR("Andreas Oberritter "); -#ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); -#endif MODULE_PARM(debug, "i"); -#endif diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/cx24110.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/cx24110.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/cx24110.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/cx24110.c 2003-10-14 02:49:47.000000000 -0700 @@ -643,7 +643,7 @@ static int cx24110_ioctl (struct dvb_fro } -static int cx24110_attach (struct dvb_i2c_bus *i2c) +static int cx24110_attach (struct dvb_i2c_bus *i2c, void **data) { u8 sig; @@ -651,13 +651,11 @@ static int cx24110_attach (struct dvb_i2 if ( sig != 0x5a && sig != 0x69 ) return -ENODEV; - dvb_register_frontend (cx24110_ioctl, i2c, NULL, &cx24110_info); - - return 0; + return dvb_register_frontend (cx24110_ioctl, i2c, NULL, &cx24110_info); } -static void cx24110_detach (struct dvb_i2c_bus *i2c) +static void cx24110_detach (struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend (cx24110_ioctl, i2c); } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/dvb_dummy_fe.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/dvb_dummy_fe.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/dvb_dummy_fe.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/dvb_dummy_fe.c 2003-10-14 02:49:47.000000000 -0700 @@ -173,14 +173,13 @@ static int dvbdummyfe_ioctl (struct dvb_ } -static int dvbdummyfe_attach (struct dvb_i2c_bus *i2c) +static int dvbdummyfe_attach (struct dvb_i2c_bus *i2c, void **data) { - dvb_register_frontend (dvbdummyfe_ioctl, i2c, NULL, frontend_info()); - return 0; + return dvb_register_frontend (dvbdummyfe_ioctl, i2c, NULL, frontend_info()); } -static void dvbdummyfe_detach (struct dvb_i2c_bus *i2c) +static void dvbdummyfe_detach (struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend (dvbdummyfe_ioctl, i2c); } @@ -191,14 +190,12 @@ static int __init init_dvbdummyfe (void) return dvb_register_i2c_device (THIS_MODULE, dvbdummyfe_attach, dvbdummyfe_detach); - return 0; } static void __exit exit_dvbdummyfe (void) { dvb_unregister_i2c_device (dvbdummyfe_attach); - return; } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/grundig_29504-401.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/grundig_29504-401.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/grundig_29504-401.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/grundig_29504-401.c 2003-10-14 02:49:47.000000000 -0700 @@ -415,7 +415,7 @@ int grundig_29504_401_ioctl (struct dvb_ } -static int l64781_attach (struct dvb_i2c_bus *i2c) +static int l64781_attach (struct dvb_i2c_bus *i2c, void **data) { u8 reg0x3e; u8 b0 [] = { 0x1a }; @@ -465,9 +465,8 @@ static int l64781_attach (struct dvb_i2c goto bailout; } - dvb_register_frontend (grundig_29504_401_ioctl, i2c, NULL, + return dvb_register_frontend (grundig_29504_401_ioctl, i2c, NULL, &grundig_29504_401_info); - return 0; bailout: l64781_writereg (i2c, 0x3e, reg0x3e); /* restore reg 0x3e */ @@ -475,7 +474,8 @@ static int l64781_attach (struct dvb_i2c } -static void l64781_detach (struct dvb_i2c_bus *i2c) + +static void l64781_detach (struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend (grundig_29504_401_ioctl, i2c); } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/grundig_29504-491.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/grundig_29504-491.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/grundig_29504-491.c 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/grundig_29504-491.c 2003-10-14 02:49:47.000000000 -0700 @@ -433,19 +433,17 @@ static int grundig_29504_491_ioctl (stru } -static int tda8083_attach (struct dvb_i2c_bus *i2c) +static int tda8083_attach (struct dvb_i2c_bus *i2c, void **data) { if ((tda8083_readreg (i2c, 0x00)) != 0x05) return -ENODEV; - dvb_register_frontend (grundig_29504_491_ioctl, i2c, NULL, + return dvb_register_frontend (grundig_29504_491_ioctl, i2c, NULL, &grundig_29504_491_info); - - return 0; } -static void tda8083_detach (struct dvb_i2c_bus *i2c) +static void tda8083_detach (struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend (grundig_29504_491_ioctl, i2c); } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/mt312.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/mt312.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/mt312.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/mt312.c 2003-10-14 02:49:47.000000000 -0700 @@ -714,7 +714,7 @@ static int mt312_ioctl(struct dvb_fronte return 0; } -static int mt312_attach(struct dvb_i2c_bus *i2c) +static int mt312_attach(struct dvb_i2c_bus *i2c, void **data) { int ret; u8 id; @@ -734,7 +734,7 @@ static int mt312_attach(struct dvb_i2c_b return 0; } -static void mt312_detach(struct dvb_i2c_bus *i2c) +static void mt312_detach(struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend(mt312_ioctl, i2c); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/nxt6000.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/nxt6000.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/nxt6000.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/nxt6000.c 2003-10-14 02:49:47.000000000 -0700 @@ -829,7 +829,7 @@ static int nxt6000_ioctl(struct dvb_fron static u8 demod_addr_tbl[] = {0x14, 0x18, 0x24, 0x28}; -static int nxt6000_attach(struct dvb_i2c_bus *i2c) +static int nxt6000_attach(struct dvb_i2c_bus *i2c, void **data) { u8 addr_nr; @@ -881,13 +881,14 @@ static int nxt6000_attach(struct dvb_i2c dvb_register_frontend(nxt6000_ioctl, i2c, (void *)(*((u32 *)&nxt)), &nxt6000_info); + fe_count++; } return (fe_count > 0) ? 0 : -ENODEV; } -static void nxt6000_detach(struct dvb_i2c_bus *i2c) +static void nxt6000_detach(struct dvb_i2c_bus *i2c, void *data) { dprintk("nxt6000: detach\n"); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/sp887x.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/sp887x.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/sp887x.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/sp887x.c 2003-10-14 02:49:47.000000000 -0700 @@ -561,7 +561,7 @@ int sp887x_ioctl (struct dvb_frontend *f static -int sp887x_attach (struct dvb_i2c_bus *i2c) +int sp887x_attach (struct dvb_i2c_bus *i2c, void **data) { struct i2c_msg msg = { addr: 0x70, flags: 0, buf: NULL, len: 0 }; @@ -570,14 +570,12 @@ int sp887x_attach (struct dvb_i2c_bus *i if (i2c->xfer (i2c, &msg, 1) != 1) return -ENODEV; - dvb_register_frontend (sp887x_ioctl, i2c, NULL, &sp887x_info); - - return 0; + return dvb_register_frontend (sp887x_ioctl, i2c, NULL, &sp887x_info); } static -void sp887x_detach (struct dvb_i2c_bus *i2c) +void sp887x_detach (struct dvb_i2c_bus *i2c, void *data) { dprintk ("%s\n", __FUNCTION__); dvb_unregister_frontend (sp887x_ioctl, i2c); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/stv0299.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/stv0299.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/stv0299.c 2003-10-08 12:24:53.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/stv0299.c 2003-10-14 02:49:47.000000000 -0700 @@ -910,7 +910,7 @@ static long probe_tuner (struct dvb_i2c_ } -static int uni0299_attach (struct dvb_i2c_bus *i2c) +static int uni0299_attach (struct dvb_i2c_bus *i2c, void **data) { long tuner_type; u8 id; @@ -928,17 +928,14 @@ static int uni0299_attach (struct dvb_i2 if ((tuner_type = probe_tuner(i2c)) < 0) return -ENODEV; - dvb_register_frontend (uni0299_ioctl, i2c, (void*) tuner_type, + return dvb_register_frontend (uni0299_ioctl, i2c, (void*) tuner_type, &uni0299_info); - - return 0; } -static void uni0299_detach (struct dvb_i2c_bus *i2c) +static void uni0299_detach (struct dvb_i2c_bus *i2c, void *data) { dprintk ("%s\n", __FUNCTION__); - dvb_unregister_frontend (uni0299_ioctl, i2c); } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/tda1004x.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/tda1004x.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/tda1004x.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/tda1004x.c 2003-10-14 02:49:47.000000000 -0700 @@ -1055,7 +1055,7 @@ static int tda1004x_ioctl(struct dvb_fro } -static int tda1004x_attach(struct dvb_i2c_bus *i2c) +static int tda1004x_attach(struct dvb_i2c_bus *i2c, void **data) { int tda1004x_address = -1; int tuner_address = -1; @@ -1113,17 +1113,15 @@ static int tda1004x_attach(struct dvb_i2 // register switch(tda_state.tda1004x_address) { case TDA10045H_ADDRESS: - dvb_register_frontend(tda1004x_ioctl, i2c, (void *)(*((u32*) &tda_state)), &tda10045h_info); - break; + return dvb_register_frontend(tda1004x_ioctl, i2c, (void *)(*((u32*) &tda_state)), &tda10045h_info); + default: + return -ENODEV; } - - // success - return 0; } static -void tda1004x_detach(struct dvb_i2c_bus *i2c) +void tda1004x_detach(struct dvb_i2c_bus *i2c, void *data) { dprintk("%s\n", __FUNCTION__); diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/ves1820.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/ves1820.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/ves1820.c 2003-10-08 12:24:06.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/ves1820.c 2003-10-14 02:49:47.000000000 -0700 @@ -507,9 +507,9 @@ static long probe_demod_addr (struct dvb } -static int ves1820_attach (struct dvb_i2c_bus *i2c) +static int ves1820_attach (struct dvb_i2c_bus *i2c, void **data) { - void *data = NULL; + void *priv = NULL; long demod_addr; long tuner_type; @@ -522,21 +522,19 @@ static int ves1820_attach (struct dvb_i2 if ((i2c->adapter->num < MAX_UNITS) && pwm[i2c->adapter->num] != -1) { printk("DVB: VES1820(%d): pwm=0x%02x (user specified)\n", i2c->adapter->num, pwm[i2c->adapter->num]); - SET_PWM(data, pwm[i2c->adapter->num]); + SET_PWM(priv, pwm[i2c->adapter->num]); } else - SET_PWM(data, read_pwm(i2c)); - SET_REG0(data, ves1820_inittab[0]); - SET_TUNER(data, tuner_type); - SET_DEMOD_ADDR(data, demod_addr); + SET_PWM(priv, read_pwm(i2c)); + SET_REG0(priv, ves1820_inittab[0]); + SET_TUNER(priv, tuner_type); + SET_DEMOD_ADDR(priv, demod_addr); - dvb_register_frontend (ves1820_ioctl, i2c, data, &ves1820_info); - - return 0; + return dvb_register_frontend (ves1820_ioctl, i2c, priv, &ves1820_info); } -static void ves1820_detach (struct dvb_i2c_bus *i2c) +static void ves1820_detach (struct dvb_i2c_bus *i2c, void *data) { dvb_unregister_frontend (ves1820_ioctl, i2c); } diff -prauN linux-2.6.0-test7/drivers/media/dvb/frontends/ves1x93.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/ves1x93.c --- linux-2.6.0-test7/drivers/media/dvb/frontends/ves1x93.c 1969-12-31 16:00:00.000000000 -0800 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/frontends/ves1x93.c 2003-10-14 02:49:47.000000000 -0700 @@ -0,0 +1,619 @@ +/* + Driver for VES1893 and VES1993 QPSK Frontends + + Copyright (C) 1999 Convergence Integrated Media GmbH + Copyright (C) 2001 Ronny Strutz <3des@tuxbox.org> + Copyright (C) 2002 Dennis Noermann + Copyright (C) 2002-2003 Andreas Oberritter + + 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. + +*/ + +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" + +static int debug = 0; +#define dprintk if (debug) printk + +static int board_type = 0; +#define BOARD_SIEMENS_PCI 0 +#define BOARD_NOKIA_DBOX2 1 +#define BOARD_SAGEM_DBOX2 2 + +static int demod_type = 0; +#define DEMOD_VES1893 0 +#define DEMOD_VES1993 1 + +static struct dvb_frontend_info ves1x93_info = { + .name = "VES1x93", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 250, /* kHz for QPSK frontends */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 50, /* 1/20 s */ + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK +}; + + +/** + * nokia dbox2 (ves1893) and sagem dbox2 (ves1993) + * need bit AGCR[PWMS] set to 1 + */ + +static u8 init_1893_tab [] = { + 0x01, 0xa4, 0x35, 0x81, 0x2a, 0x0d, 0x55, 0xc4, + 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x31, 0xb0, 0x14, 0x00, 0xdc, 0x00, + 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 +}; + + +static u8 init_1993_tab [] = { + 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c, + 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, + 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10, + 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x0e, 0x80, 0x00 +}; + + +static u8 * init_1x93_tab; + + +static u8 init_1893_wtab[] = +{ + 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, + 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, + 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, + 1,1,1,0,1,1 +}; + + +static u8 init_1993_wtab[] = +{ + 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, + 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1, + 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, + 1,1,1,0,1,1,1,1, 1,1,1,1,1 +}; + + +static int ves1x93_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +{ + u8 buf [] = { 0x00, reg, data }; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; + int err; + + if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { + dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); + return -EREMOTEIO; + } + + return 0; +} + + +static u8 ves1x93_readreg (struct dvb_i2c_bus *i2c, u8 reg) +{ + int ret; + u8 b0 [] = { 0x00, reg }; + u8 b1 [] = { 0 }; + struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; + + ret = i2c->xfer (i2c, msg, 2); + + if (ret != 2) + dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + + return b1[0]; +} + + +static int tuner_write (struct dvb_i2c_bus *i2c, u8 *data, u8 len) +{ + int ret; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = len }; + + ves1x93_writereg(i2c, 0x00, 0x11); + ret = i2c->xfer (i2c, &msg, 1); + ves1x93_writereg(i2c, 0x00, 0x01); + + if (ret != 1) + printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret); + + return (ret != 1) ? -1 : 0; +} + + + +/** + * set up the downconverter frequency divisor for a + * reference clock comparision frequency of 125 kHz. + */ +static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) +{ + u32 div = (freq + 479500) / 125; + u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 }; + + return tuner_write (i2c, buf, sizeof(buf)); +} + + +static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +{ + int ret; + u8 buf [2]; + + freq /= 1000; + + buf[0] = (freq >> 8) & 0x7F; + buf[1] = freq & 0xFF; + + ret = tuner_write(i2c, buf, sizeof(buf)); + + return ret; +} + + +static int tuner_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) +{ + if ((demod_type == DEMOD_VES1893) && (board_type == BOARD_SIEMENS_PCI)) + return sp5659_set_tv_freq (i2c, freq, pwr); + else if (demod_type == DEMOD_VES1993) + return tsa5059_set_tv_freq (i2c, freq); + + return -EINVAL; +} + + +static int ves1x93_init (struct dvb_i2c_bus *i2c) +{ + int i; + int size; + u8 *init_1x93_wtab; + + dprintk("%s: init chip\n", __FUNCTION__); + + switch (demod_type) { + case DEMOD_VES1893: + init_1x93_tab = init_1893_tab; + init_1x93_wtab = init_1893_wtab; + size = sizeof(init_1893_tab); + if (board_type == BOARD_NOKIA_DBOX2) + init_1x93_tab[0x05] |= 0x20; /* invert PWM */ + break; + + case DEMOD_VES1993: + init_1x93_tab = init_1993_tab; + init_1x93_wtab = init_1993_wtab; + size = sizeof(init_1993_tab); + if (board_type == BOARD_SAGEM_DBOX2) + init_1x93_tab[0x05] |= 0x20; /* invert PWM */ + break; + + default: + return -EINVAL; + } + + for (i = 0; i < size; i++) + if (init_1x93_wtab[i]) + ves1x93_writereg (i2c, i, init_1x93_tab[i]); + + if (demod_type == DEMOD_VES1993) { + if (board_type == BOARD_NOKIA_DBOX2) + tuner_write(i2c, "\x06\x5c\x83\x60", 4); + else if (board_type == BOARD_SAGEM_DBOX2) + tuner_write(i2c, "\x25\x70\x92\x40", 4); + } + + return 0; +} + + +static int ves1x93_clr_bit (struct dvb_i2c_bus *i2c) +{ + ves1x93_writereg (i2c, 0, init_1x93_tab[0] & 0xfe); + ves1x93_writereg (i2c, 0, init_1x93_tab[0]); + ves1x93_writereg (i2c, 3, 0x00); + return ves1x93_writereg (i2c, 3, init_1x93_tab[3]); +} + + +static int ves1x93_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) +{ + u8 val; + + /* + * inversion on/off are interchanged because i and q seem to + * be swapped on the hardware + */ + + switch (inversion) { + case INVERSION_OFF: + val = 0xc0; + break; + case INVERSION_ON: + val = 0x80; + break; + case INVERSION_AUTO: + val = 0x00; + break; + default: + return -EINVAL; + } + + /* needs to be saved for FE_GET_FRONTEND */ + init_1x93_tab[0x0c] = (init_1x93_tab[0x0c] & 0x3f) | val; + + return ves1x93_writereg (i2c, 0x0c, init_1x93_tab[0x0c]); +} + + +static int ves1x93_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +{ + if (fec == FEC_AUTO) + return ves1x93_writereg (i2c, 0x0d, 0x08); + else if (fec < FEC_1_2 || fec > FEC_8_9) + return -EINVAL; + else + return ves1x93_writereg (i2c, 0x0d, fec - FEC_1_2); +} + + +static fe_code_rate_t ves1x93_get_fec (struct dvb_i2c_bus *i2c) +{ + return FEC_1_2 + ((ves1x93_readreg (i2c, 0x0d) >> 4) & 0x7); +} + + +static int ves1x93_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +{ + u32 BDR; + u32 ratio; + u8 ADCONF, FCONF, FNR; + u32 BDRI; + u32 tmp; + u32 XIN, FIN; + + dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate); + + switch (board_type) { + case BOARD_SIEMENS_PCI: + XIN = 90100000UL; + break; + case BOARD_NOKIA_DBOX2: + if (demod_type == DEMOD_VES1893) + XIN = 91000000UL; + else if (demod_type == DEMOD_VES1993) + XIN = 96000000UL; + else + return -EINVAL; + break; + case BOARD_SAGEM_DBOX2: + XIN = 92160000UL; + break; + default: + return -EINVAL; + } + + if (srate > XIN/2) + srate = XIN/2; + + if (srate < 500000) + srate = 500000; + +#define MUL (1UL<<26) + + FIN = (XIN + 6000) >> 4; + + tmp = srate << 6; + ratio = tmp / FIN; + + tmp = (tmp % FIN) << 8; + ratio = (ratio << 8) + tmp / FIN; + + tmp = (tmp % FIN) << 8; + ratio = (ratio << 8) + tmp / FIN; + + FNR = 0xff; + + if (ratio < MUL/3) FNR = 0; + if (ratio < (MUL*11)/50) FNR = 1; + if (ratio < MUL/6) FNR = 2; + if (ratio < MUL/9) FNR = 3; + if (ratio < MUL/12) FNR = 4; + if (ratio < (MUL*11)/200) FNR = 5; + if (ratio < MUL/24) FNR = 6; + if (ratio < (MUL*27)/1000) FNR = 7; + if (ratio < MUL/48) FNR = 8; + if (ratio < (MUL*137)/10000) FNR = 9; + + if (FNR == 0xff) { + ADCONF = 0x89; + FCONF = 0x80; + FNR = 0; + } else { + ADCONF = 0x81; + FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); + /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/ + } + + BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; + BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; + + dprintk("FNR= %d\n", FNR); + dprintk("ratio= %08x\n", (unsigned int) ratio); + dprintk("BDR= %08x\n", (unsigned int) BDR); + dprintk("BDRI= %02x\n", (unsigned int) BDRI); + + if (BDRI > 0xff) + BDRI = 0xff; + + ves1x93_writereg (i2c, 0x06, 0xff & BDR); + ves1x93_writereg (i2c, 0x07, 0xff & (BDR >> 8)); + ves1x93_writereg (i2c, 0x08, 0x0f & (BDR >> 16)); + + ves1x93_writereg (i2c, 0x09, BDRI); + ves1x93_writereg (i2c, 0x20, ADCONF); + ves1x93_writereg (i2c, 0x21, FCONF); + + if (srate < 6000000) + ves1x93_writereg (i2c, 0x05, init_1x93_tab[0x05] | 0x80); + else + ves1x93_writereg (i2c, 0x05, init_1x93_tab[0x05] & 0x7f); + + ves1x93_writereg (i2c, 0x00, 0x00); + ves1x93_writereg (i2c, 0x00, 0x01); + + /* ves1993 hates this, will lose lock */ + if (demod_type != DEMOD_VES1993) + ves1x93_clr_bit (i2c); + + return 0; +} + + +static int ves1x93_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +{ + switch (voltage) { + case SEC_VOLTAGE_13: + return ves1x93_writereg (i2c, 0x1f, 0x20); + case SEC_VOLTAGE_18: + return ves1x93_writereg (i2c, 0x1f, 0x30); + case SEC_VOLTAGE_OFF: + return ves1x93_writereg (i2c, 0x1f, 0x00); + default: + return -EINVAL; + } +} + + +static int ves1x93_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +{ + struct dvb_i2c_bus *i2c = fe->i2c; + + switch (cmd) { + case FE_GET_INFO: + memcpy (arg, &ves1x93_info, sizeof(struct dvb_frontend_info)); + break; + + case FE_READ_STATUS: + { + fe_status_t *status = arg; + u8 sync = ves1x93_readreg (i2c, 0x0e); + + *status = 0; + + if (sync & 1) + *status |= FE_HAS_SIGNAL; + + if (sync & 2) + *status |= FE_HAS_CARRIER; + + if (sync & 4) + *status |= FE_HAS_VITERBI; + + if (sync & 8) + *status |= FE_HAS_SYNC; + + if ((sync & 0x1f) == 0x1f) + *status |= FE_HAS_LOCK; + + break; + } + + case FE_READ_BER: + { + u32 *ber = (u32 *) arg; + + *ber = ves1x93_readreg (i2c, 0x15); + *ber |= (ves1x93_readreg (i2c, 0x16) << 8); + *ber |= ((ves1x93_readreg (i2c, 0x17) & 0x0F) << 16); + *ber *= 10; + break; + } + + case FE_READ_SIGNAL_STRENGTH: + { + u8 signal = ~ves1x93_readreg (i2c, 0x0b); + *((u16*) arg) = (signal << 8) | signal; + break; + } + + case FE_READ_SNR: + { + u8 snr = ~ves1x93_readreg (i2c, 0x1c); + *(u16*) arg = (snr << 8) | snr; + break; + } + + case FE_READ_UNCORRECTED_BLOCKS: + { + *(u32*) arg = ves1x93_readreg (i2c, 0x18) & 0x7f; + + if (*(u32*) arg == 0x7f) + *(u32*) arg = 0xffffffff; /* counter overflow... */ + + ves1x93_writereg (i2c, 0x18, 0x00); /* reset the counter */ + ves1x93_writereg (i2c, 0x18, 0x80); /* dto. */ + break; + } + + case FE_SET_FRONTEND: + { + struct dvb_frontend_parameters *p = arg; + + tuner_set_tv_freq (i2c, p->frequency, 0); + ves1x93_set_inversion (i2c, p->inversion); + ves1x93_set_fec (i2c, p->u.qpsk.fec_inner); + ves1x93_set_symbolrate (i2c, p->u.qpsk.symbol_rate); + break; + } + + case FE_GET_FRONTEND: + { + struct dvb_frontend_parameters *p = arg; + int afc; + + afc = ((int)((char)(ves1x93_readreg (i2c, 0x0a) << 1)))/2; + afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; + + p->frequency -= afc; + + /* + * inversion indicator is only valid + * if auto inversion was used + */ + if (!(init_1x93_tab[0x0c] & 0x80)) + p->inversion = (ves1x93_readreg (i2c, 0x0f) & 2) ? + INVERSION_OFF : INVERSION_ON; + p->u.qpsk.fec_inner = ves1x93_get_fec (i2c); + /* XXX FIXME: timing offset !! */ + break; + } + + case FE_SLEEP: + if (board_type == BOARD_SIEMENS_PCI) + ves1x93_writereg (i2c, 0x1f, 0x00); /* LNB power off */ + return ves1x93_writereg (i2c, 0x00, 0x08); + + case FE_INIT: + return ves1x93_init (i2c); + + case FE_RESET: + return ves1x93_clr_bit (i2c); + + case FE_SET_TONE: + return -EOPNOTSUPP; /* the ves1893 can generate the 22k */ + /* let's implement this when we have */ + /* a box that uses the 22K_0 pin... */ + + case FE_SET_VOLTAGE: + return ves1x93_set_voltage (i2c, (fe_sec_voltage_t) arg); + + default: + return -EOPNOTSUPP; + }; + + return 0; +} + + +static int ves1x93_attach (struct dvb_i2c_bus *i2c, void **data) +{ + u8 identity = ves1x93_readreg(i2c, 0x1e); + + switch (identity) { + case 0xdc: /* VES1893A rev1 */ + case 0xdd: /* VES1893A rev2 */ + demod_type = DEMOD_VES1893; + ves1x93_info.name[4] = '8'; + break; + case 0xde: /* VES1993 */ + demod_type = DEMOD_VES1993; + ves1x93_info.name[4] = '9'; + break; + default: + dprintk("VES1x93 not found (identity %02x)\n", identity); + return -ENODEV; + } + + return dvb_register_frontend (ves1x93_ioctl, i2c, NULL, &ves1x93_info); +} + + +static void ves1x93_detach (struct dvb_i2c_bus *i2c, void *data) +{ + dvb_unregister_frontend (ves1x93_ioctl, i2c); +} + + +static int __init init_ves1x93 (void) +{ + switch (board_type) { + case BOARD_NOKIA_DBOX2: + dprintk("%s: NOKIA_DBOX2\n", __FILE__); + break; + case BOARD_SAGEM_DBOX2: + dprintk("%s: SAGEM_DBOX2\n", __FILE__); + break; + case BOARD_SIEMENS_PCI: + dprintk("%s: SIEMENS_PCI\n", __FILE__); + break; + default: + return -EIO; + } + + return dvb_register_i2c_device (THIS_MODULE, ves1x93_attach, ves1x93_detach); +} + + +static void __exit exit_ves1x93 (void) +{ + dvb_unregister_i2c_device (ves1x93_attach); +} + + +module_init(init_ves1x93); +module_exit(exit_ves1x93); + + +MODULE_DESCRIPTION("VES1x93 DVB-S Frontend"); +MODULE_AUTHOR("Ralph Metzler"); +MODULE_LICENSE("GPL"); +MODULE_PARM(debug,"i"); +MODULE_PARM(board_type,"i"); + diff -prauN linux-2.6.0-test7/drivers/media/dvb/ttpci/av7110.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttpci/av7110.c --- linux-2.6.0-test7/drivers/media/dvb/ttpci/av7110.c 2003-10-08 12:24:17.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttpci/av7110.c 2003-10-14 02:49:47.000000000 -0700 @@ -55,8 +55,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -4520,28 +4522,6 @@ static int av7110_attach (struct saa7146 DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); - /* special case DVB-C: these cards have an analog tuner - plus need some special handling, so we have separate - saa7146_ext_vv data for these... */ - if (dev->pci->subsystem_vendor == 0x110a) { - ret = saa7146_vv_init(dev, &av7110_vv_data_c); - } else { - ret = saa7146_vv_init(dev, &av7110_vv_data_st); - } - - if ( 0 != ret) { - ERR(("cannot init capture device. skipping.\n")); - kfree(av7110); - return -1; - } - - if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture device. skipping.\n")); - saa7146_vv_release(dev); - kfree(av7110); - return -1; - } - av7110->dev=(struct saa7146_dev *)dev; dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name); @@ -4555,8 +4535,6 @@ static int av7110_attach (struct saa7146 av7110->dvb_adapter, 0); if (!av7110->i2c_bus) { - saa7146_unregister_device(&av7110->v4l_dev, dev); - saa7146_vv_release(dev); dvb_unregister_adapter (av7110->dvb_adapter); kfree(av7110); return -ENOMEM; @@ -4727,7 +4705,7 @@ static int av7110_attach (struct saa7146 memcpy(standard,dvb_standard,sizeof(struct saa7146_standard)*2); /* set dd1 stream a & b */ saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x0200700); + saa7146_write(dev, DD1_INIT, 0x02000700); saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); } else if (dev->pci->subsystem_vendor == 0x110a) { @@ -4754,17 +4732,52 @@ static int av7110_attach (struct saa7146 av7110_setup_irc_config (av7110, 0); av7110_register(av7110); + /* special case DVB-C: these cards have an analog tuner + plus need some special handling, so we have separate + saa7146_ext_vv data for these... */ + if (0 != av7110->has_analog_tuner) { + ret = saa7146_vv_init(dev, &av7110_vv_data_c); + } else { + ret = saa7146_vv_init(dev, &av7110_vv_data_st); + } + + if ( 0 != ret) { + ERR(("cannot init capture device. skipping.\n")); + ret = -ENODEV; + goto err; + } + + if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { + ERR(("cannot register capture device. skipping.\n")); + ret = -ENODEV; + goto video_err; + } + + if (0 != av7110->has_analog_tuner) { + if( 0 != saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { + ERR(("cannot register vbi v4l2 device. skipping.\n")); + } + /* we use this to remember that this dvb-c card cannot do vbi */ + av7110->has_analog_tuner = 2; + } + printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num); av7110_num++; return 0; +video_err: + saa7146_vv_release(dev); + err: - if (av7110 ) + if (NULL != av7110 ) { kfree(av7110); - - /* FIXME: error handling is pretty bogus: memory does not get freed...*/ - saa7146_unregister_device(&av7110->v4l_dev, dev); - saa7146_vv_release(dev); + } + if (NULL != av7110->debi_virt) { + pci_free_consistent(dev->pci, 8192, av7110->debi_virt, av7110->debi_bus); + } + if (NULL != av7110->iobuf) { + vfree(av7110->iobuf); + } dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); @@ -4780,6 +4793,9 @@ static int av7110_detach (struct saa7146 DEB_EE(("av7110: %p\n",av7110)); saa7146_unregister_device(&av7110->v4l_dev, saa); + if (2 == av7110->has_analog_tuner) { + saa7146_unregister_device(&av7110->vbi_dev, saa); + } av7110->arm_rmmod=1; wake_up_interruptible(&av7110->arm_wait); @@ -4948,8 +4964,8 @@ static struct saa7146_ext_vv av7110_vv_d static struct saa7146_ext_vv av7110_vv_data_c = { .inputs = 1, .audios = 1, - .capabilities = V4L2_CAP_TUNER, - .flags = 0, + .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, + .flags = SAA7146_USE_PORT_B_FOR_VBI, .stds = &standard[0], .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), diff -prauN linux-2.6.0-test7/drivers/media/dvb/ttpci/av7110.h wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttpci/av7110.h --- linux-2.6.0-test7/drivers/media/dvb/ttpci/av7110.h 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttpci/av7110.h 2003-10-14 02:49:47.000000000 -0700 @@ -399,7 +399,9 @@ struct av7110 { struct dvb_device dvb_dev; struct dvb_net dvb_net; + struct video_device v4l_dev; + struct video_device vbi_dev; struct saa7146_dev *dev; diff -prauN linux-2.6.0-test7/drivers/media/dvb/ttusb-dec/dec2000_frontend.c wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttusb-dec/dec2000_frontend.c --- linux-2.6.0-test7/drivers/media/dvb/ttusb-dec/dec2000_frontend.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/dvb/ttusb-dec/dec2000_frontend.c 2003-10-14 02:49:47.000000000 -0700 @@ -140,17 +140,15 @@ static int dec2000_frontend_ioctl(struct return 0; } -static int dec2000_frontend_attach(struct dvb_i2c_bus *i2c) +static int dec2000_frontend_attach(struct dvb_i2c_bus *i2c, void **data) { dprintk("%s\n", __FUNCTION__); - dvb_register_frontend(dec2000_frontend_ioctl, i2c, NULL, + return dvb_register_frontend(dec2000_frontend_ioctl, i2c, NULL, &dec2000_frontend_info); - - return 0; } -static void dec2000_frontend_detach(struct dvb_i2c_bus *i2c) +static void dec2000_frontend_detach(struct dvb_i2c_bus *i2c, void *data) { dprintk("%s\n", __FUNCTION__); diff -prauN linux-2.6.0-test7/drivers/media/video/zoran_card.c wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_card.c --- linux-2.6.0-test7/drivers/media/video/zoran_card.c 2003-10-08 12:24:14.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_card.c 2003-10-14 02:49:47.000000000 -0700 @@ -47,6 +47,8 @@ #include #include +#include + #include "videocodec.h" #include "zoran.h" #include "zoran_card.h" diff -prauN linux-2.6.0-test7/drivers/media/video/zoran_device.c wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_device.c --- linux-2.6.0-test7/drivers/media/video/zoran_device.c 2003-10-08 12:24:08.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_device.c 2003-10-14 02:49:47.000000000 -0700 @@ -46,6 +46,8 @@ #include #include +#include + #include "videocodec.h" #include "zoran.h" #include "zoran_device.h" diff -prauN linux-2.6.0-test7/drivers/media/video/zoran_driver.c wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_driver.c --- linux-2.6.0-test7/drivers/media/video/zoran_driver.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/media/video/zoran_driver.c 2003-10-14 02:49:47.000000000 -0700 @@ -73,6 +73,7 @@ #include #include "videocodec.h" +#include #include #include diff -prauN linux-2.6.0-test7/drivers/mtd/devices/lart.c wli-2.6.0-test7-bk5-36/drivers/mtd/devices/lart.c --- linux-2.6.0-test7/drivers/mtd/devices/lart.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/mtd/devices/lart.c 2003-10-14 02:49:47.000000000 -0700 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #ifdef HAVE_PARTITIONS diff -prauN linux-2.6.0-test7/drivers/net/hamradio/Kconfig wli-2.6.0-test7-bk5-36/drivers/net/hamradio/Kconfig --- linux-2.6.0-test7/drivers/net/hamradio/Kconfig 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/hamradio/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -159,7 +159,7 @@ config BAYCOM_PAR config BAYCOM_EPP tristate "BAYCOM epp driver for AX.25" - depends on PARPORT && AX25 + depends on PARPORT && AX25 && !64BIT ---help--- This is a driver for Baycom style simple amateur radio modems that connect to a parallel interface. The driver supports the EPP diff -prauN linux-2.6.0-test7/drivers/net/irda/sa1100_ir.c wli-2.6.0-test7-bk5-36/drivers/net/irda/sa1100_ir.c --- linux-2.6.0-test7/drivers/net/irda/sa1100_ir.c 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/irda/sa1100_ir.c 2003-10-14 02:49:47.000000000 -0700 @@ -1132,12 +1132,8 @@ static void __exit sa1100_irda_exit(void release_mem_region(__PREG(Ser2HSCR0), 0x1c); release_mem_region(__PREG(Ser2UTCR0), 0x24); - /* - * We now know that the netdevice is no longer in use, and all - * references to our driver have been removed. The only structure - * which may still be present is the netdevice, which will get - * cleaned up by net/core/dev.c - */ + if(dev) + free_netdev(dev); } static int __init sa1100ir_setup(char *line) diff -prauN linux-2.6.0-test7/drivers/net/loopback.c wli-2.6.0-test7-bk5-36/drivers/net/loopback.c --- linux-2.6.0-test7/drivers/net/loopback.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/loopback.c 2003-10-14 02:49:47.000000000 -0700 @@ -125,19 +125,7 @@ static int loopback_xmit(struct sk_buff { struct net_device_stats *stats = (struct net_device_stats *)dev->priv; - /* - * Optimise so buffers with skb->free=1 are not copied but - * instead are lobbed from tx queue to rx queue - */ - - if (skb_shared(skb)) { - struct sk_buff *skb2=skb; - skb=skb_clone(skb, GFP_ATOMIC); /* Clone the buffer */ - kfree_skb(skb2); - if (unlikely(skb==NULL)) - return 0; - } else - skb_orphan(skb); + skb_orphan(skb); skb->protocol=eth_type_trans(skb,dev); skb->dev=dev; diff -prauN linux-2.6.0-test7/drivers/net/slip.c wli-2.6.0-test7-bk5-36/drivers/net/slip.c --- linux-2.6.0-test7/drivers/net/slip.c 2003-10-08 12:24:53.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/slip.c 2003-10-14 02:49:47.000000000 -0700 @@ -1307,7 +1307,7 @@ static int sl_ioctl(struct net_device *d /* Resolve race condition, when ioctl'ing hanged up and opened by another process device. */ - if (sl->tty != process_tty(current) && sl->pid != current->pid) { + if (sl->tty != current->tty && sl->pid != current->pid) { spin_unlock_bh(&sl->lock); return -EPERM; } diff -prauN linux-2.6.0-test7/drivers/net/sungem.c wli-2.6.0-test7-bk5-36/drivers/net/sungem.c --- linux-2.6.0-test7/drivers/net/sungem.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/sungem.c 2003-10-14 02:49:47.000000000 -0700 @@ -2731,6 +2731,19 @@ static int __devinit gem_init_one(struct if (gem_get_device_address(gp)) goto err_out_free_consistent; + dev->open = gem_open; + dev->stop = gem_close; + dev->hard_start_xmit = gem_start_xmit; + dev->get_stats = gem_get_stats; + dev->set_multicast_list = gem_set_multicast; + dev->do_ioctl = gem_ioctl; + dev->ethtool_ops = &gem_ethtool_ops; + dev->tx_timeout = gem_tx_timeout; + dev->watchdog_timeo = 5 * HZ; + dev->change_mtu = gem_change_mtu; + dev->irq = pdev->irq; + dev->dma = 0; + if (register_netdev(dev)) { printk(KERN_ERR PFX "Cannot register net device, " "aborting.\n"); @@ -2759,19 +2772,6 @@ static int __devinit gem_init_one(struct pci_set_drvdata(pdev, dev); - dev->open = gem_open; - dev->stop = gem_close; - dev->hard_start_xmit = gem_start_xmit; - dev->get_stats = gem_get_stats; - dev->set_multicast_list = gem_set_multicast; - dev->do_ioctl = gem_ioctl; - dev->ethtool_ops = &gem_ethtool_ops; - dev->tx_timeout = gem_tx_timeout; - dev->watchdog_timeo = 5 * HZ; - dev->change_mtu = gem_change_mtu; - dev->irq = pdev->irq; - dev->dma = 0; - /* GEM can do it all... */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; if (pci_using_dac) diff -prauN linux-2.6.0-test7/drivers/net/wan/cosa.c wli-2.6.0-test7-bk5-36/drivers/net/wan/cosa.c --- linux-2.6.0-test7/drivers/net/wan/cosa.c 2003-10-08 12:24:00.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/wan/cosa.c 2003-10-14 02:49:47.000000000 -0700 @@ -615,7 +615,7 @@ static void sppp_channel_init(struct cha d->get_stats = cosa_net_stats; d->tx_timeout = cosa_sppp_timeout; d->watchdog_timeo = TX_TIMEOUT; - if (register_netdev(d) == -1) { + if (register_netdev(d)) { printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); sppp_detach(chan->pppdev.dev); free_netdev(chan->pppdev.dev); diff -prauN linux-2.6.0-test7/drivers/net/wan/hdlc_cisco.c wli-2.6.0-test7-bk5-36/drivers/net/wan/hdlc_cisco.c --- linux-2.6.0-test7/drivers/net/wan/hdlc_cisco.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/wan/hdlc_cisco.c 2003-10-14 02:49:47.000000000 -0700 @@ -311,7 +311,9 @@ int hdlc_cisco_ioctl(hdlc_device *hdlc, hdlc->proto.id = IF_PROTO_CISCO; dev->hard_start_xmit = hdlc->xmit; dev->hard_header = cisco_hard_header; + dev->hard_header_cache = NULL; dev->type = ARPHRD_CISCO; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->addr_len = 0; return 0; } diff -prauN linux-2.6.0-test7/drivers/net/wan/hostess_sv11.c wli-2.6.0-test7-bk5-36/drivers/net/wan/hostess_sv11.c --- linux-2.6.0-test7/drivers/net/wan/hostess_sv11.c 2003-10-08 12:24:26.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/net/wan/hostess_sv11.c 2003-10-14 02:49:47.000000000 -0700 @@ -337,7 +337,7 @@ static struct sv11_device *sv11_init(int d->neigh_setup = hostess_neigh_setup_dev; d->set_mac_address = NULL; - if(register_netdev(d)==-1) + if(register_netdev(d)) { printk(KERN_ERR "%s: unable to register device.\n", d->name); diff -prauN linux-2.6.0-test7/drivers/pci/hotplug/Kconfig wli-2.6.0-test7-bk5-36/drivers/pci/hotplug/Kconfig --- linux-2.6.0-test7/drivers/pci/hotplug/Kconfig 2003-10-08 12:24:04.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/pci/hotplug/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -44,7 +44,7 @@ config HOTPLUG_PCI_FAKE config HOTPLUG_PCI_COMPAQ tristate "Compaq PCI Hotplug driver" - depends on HOTPLUG_PCI && X86 + depends on HOTPLUG_PCI && X86 && PCI_BIOS help Say Y here if you have a motherboard with a Compaq PCI Hotplug controller. @@ -66,7 +66,7 @@ config HOTPLUG_PCI_COMPAQ_NVRAM config HOTPLUG_PCI_IBM tristate "IBM PCI Hotplug driver" - depends on HOTPLUG_PCI && X86_IO_APIC && X86 + depends on HOTPLUG_PCI && X86_IO_APIC && X86 && PCI_BIOS help Say Y here if you have a motherboard with a IBM PCI Hotplug controller. diff -prauN linux-2.6.0-test7/drivers/pcmcia/tcic.c wli-2.6.0-test7-bk5-36/drivers/pcmcia/tcic.c --- linux-2.6.0-test7/drivers/pcmcia/tcic.c 2003-10-08 12:24:08.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/pcmcia/tcic.c 2003-10-14 02:49:47.000000000 -0700 @@ -643,7 +643,7 @@ static int tcic_get_status(struct pcmcia reg = tcic_getb(TCIC_PWR); if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock))) *value |= SS_POWERON; - DEBUG(1, "tcic: GetStatus(%d) = %#2.2x\n", lsock, *value); + DEBUG(1, "tcic: GetStatus(%d) = %#2.2x\n", psock, *value); return 0; } /* tcic_get_status */ @@ -695,7 +695,7 @@ static int tcic_get_socket(struct pcmcia } DEBUG(1, "tcic: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags, + "io_irq %d, csc_mask %#2.2x\n", psock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); return 0; } /* tcic_get_socket */ @@ -709,7 +709,7 @@ static int tcic_set_socket(struct pcmcia u_short scf1, scf2; DEBUG(1, "tcic: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags, + "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags, state->Vcc, state->Vpp, state->io_irq, state->csc_mask); tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG); @@ -784,7 +784,7 @@ static int tcic_set_io_map(struct pcmcia u_short base, len, ioctl; DEBUG(1, "tcic: SetIOMap(%d, %d, %#2.2x, %d ns, " - "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags, + "%#4.4x-%#4.4x)\n", psock, io->map, io->flags, io->speed, io->start, io->stop); if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)) return -EINVAL; @@ -821,7 +821,7 @@ static int tcic_set_mem_map(struct pcmci u_long base, len, mmap; DEBUG(1, "tcic: SetMemMap(%d, %d, %#2.2x, %d ns, " - "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags, + "%#5.5lx-%#5.5lx, %#5.5x)\n", psock, mem->map, mem->flags, mem->speed, mem->sys_start, mem->sys_stop, mem->card_start); if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || (mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff) || diff -prauN linux-2.6.0-test7/drivers/scsi/scsi_sysfs.c wli-2.6.0-test7-bk5-36/drivers/scsi/scsi_sysfs.c --- linux-2.6.0-test7/drivers/scsi/scsi_sysfs.c 2003-10-08 12:24:02.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/scsi/scsi_sysfs.c 2003-10-14 02:49:47.000000000 -0700 @@ -412,7 +412,7 @@ void scsi_remove_device(struct scsi_devi set_bit(SDEV_DEL, &sdev->sdev_state); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (atomic_read(&sdev->access_count)) + if (!atomic_read(&sdev->access_count)) device_del(&sdev->sdev_gendev); up_write(&class->subsys.rwsem); } diff -prauN linux-2.6.0-test7/drivers/serial/8250_acpi.c wli-2.6.0-test7-bk5-36/drivers/serial/8250_acpi.c --- linux-2.6.0-test7/drivers/serial/8250_acpi.c 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/serial/8250_acpi.c 2003-10-14 02:49:47.000000000 -0700 @@ -38,8 +38,11 @@ static acpi_status acpi_serial_mmio(stru static acpi_status acpi_serial_port(struct serial_struct *req, struct acpi_resource_io *io) { - req->port = io->min_base_address; - req->io_type = SERIAL_IO_PORT; + if (io->range_length) { + req->port = io->min_base_address; + req->io_type = SERIAL_IO_PORT; + } else + printk(KERN_ERR "%s: zero-length IO port range?\n", __FUNCTION__); return AE_OK; } diff -prauN linux-2.6.0-test7/drivers/usb/README wli-2.6.0-test7-bk5-36/drivers/usb/README --- linux-2.6.0-test7/drivers/usb/README 2003-10-08 12:24:45.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/README 2003-10-14 02:49:47.000000000 -0700 @@ -8,7 +8,7 @@ host/ - This is for all of the USB host includes UHCI, OHCI, EHCI, and any others that might be created in the future. -device/ - This is for all of the USB device controller drivers. +gadget/ - This is for all of the USB device controller drivers. Individual USB driver directories. A new driver should be added to the @@ -16,7 +16,7 @@ first subdirectory in the list below tha image/ - This is for still image drivers, like scanners or digital cameras. -input/ - This if for any driver that uses the input subsystem, +input/ - This is for any driver that uses the input subsystem, like keyboard, mice, touchscreens, tablets, etc. media/ - This is for multimedia drivers, like video cameras, radios, and any other drivers that talk to the v4l @@ -29,5 +29,3 @@ class/ - This is for all USB device dri of USB Class specified devices. misc/ - This is for all USB device drivers that do not fit into any of the above categories. - - diff -prauN linux-2.6.0-test7/drivers/usb/class/Kconfig wli-2.6.0-test7-bk5-36/drivers/usb/class/Kconfig --- linux-2.6.0-test7/drivers/usb/class/Kconfig 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/class/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -71,7 +71,7 @@ config USB_ACM driver. To compile this driver as a module, choose M here: the - module will be called acm. + module will be called cdc-acm. config USB_PRINTER tristate "USB Printer support" diff -prauN linux-2.6.0-test7/drivers/usb/core/devio.c wli-2.6.0-test7-bk5-36/drivers/usb/core/devio.c --- linux-2.6.0-test7/drivers/usb/core/devio.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/core/devio.c 2003-10-14 02:49:47.000000000 -0700 @@ -384,7 +384,7 @@ static int releaseintf(struct dev_state err = -EINVAL; dev = ps->dev; down(&dev->serialize); - if (dev && test_and_clear_bit(intf, &ps->ifclaimed)) { + if (test_and_clear_bit(intf, &ps->ifclaimed)) { iface = dev->actconfig->interface[intf]; usb_driver_release_interface(&usbdevfs_driver, iface); err = 0; diff -prauN linux-2.6.0-test7/drivers/usb/core/hcd-pci.c wli-2.6.0-test7-bk5-36/drivers/usb/core/hcd-pci.c --- linux-2.6.0-test7/drivers/usb/core/hcd-pci.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/core/hcd-pci.c 2003-10-14 02:49:47.000000000 -0700 @@ -295,6 +295,8 @@ int usb_hcd_pci_suspend (struct pci_dev if (retval) dev_dbg (hcd->controller, "suspend fail, retval %d\n", retval); + else + hcd->state = USB_STATE_SUSPENDED; } pci_set_power_state (dev, state); diff -prauN linux-2.6.0-test7/drivers/usb/gadget/Kconfig wli-2.6.0-test7-bk5-36/drivers/usb/gadget/Kconfig --- linux-2.6.0-test7/drivers/usb/gadget/Kconfig 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/gadget/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -110,7 +110,7 @@ config USB_ZERO_SA1100 config USB_ETH tristate "Ethernet Gadget" - depends on USB_GADGET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100) + depends on USB_GADGET && NET && (USB_DUMMY_HCD || USB_NET2280 || USB_PXA2XX || USB_SA1100) help This driver implements Ethernet style communication, in either of two ways: diff -prauN linux-2.6.0-test7/drivers/usb/gadget/net2280.c wli-2.6.0-test7-bk5-36/drivers/usb/gadget/net2280.c --- linux-2.6.0-test7/drivers/usb/gadget/net2280.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/gadget/net2280.c 2003-10-14 02:49:47.000000000 -0700 @@ -50,7 +50,6 @@ #define DEBUG 1 // #define VERBOSE /* extra debug messages (success too) */ -#include #include #include #include @@ -431,6 +430,9 @@ net2280_free_request (struct usb_ep *_ep #elif defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE) #define USE_KMALLOC +#elif defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO) +#define USE_KMALLOC + /* FIXME there are other cases, including an x86-64 one ... */ #endif @@ -452,31 +454,23 @@ net2280_alloc_buffer ( ep = container_of (_ep, struct net2280_ep, ep); if (!_ep) return 0; - *dma = DMA_ADDR_INVALID; - if (ep->dma) { -#if defined(USE_KMALLOC) - retval = kmalloc (bytes, gfp_flags); - if (retval) - *dma = virt_to_phys (retval); -#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,5,58) -#warning Using dma_alloc_consistent even with sub-page allocations +#if defined(USE_KMALLOC) + retval = kmalloc(bytes, gfp_flags); + if (retval) + *dma = virt_to_phys(retval); +#else + if (ep->dma) { /* the main problem with this call is that it wastes memory * on typical 1/N page allocations: it allocates 1-N pages. */ - retval = dma_alloc_coherent (&ep->dev->pdev->dev, +#warning Using dma_alloc_coherent even with buffers smaller than a page. + retval = dma_alloc_coherent(&ep->dev->pdev->dev, bytes, dma, gfp_flags); -#else -#error No dma-coherent memory allocator is available - /* pci_alloc_consistent works, but pci_free_consistent() - * isn't safe in_interrupt(). plus, in addition to the - * 1/Nth page weakness, it doesn't understand gfp_flags. - */ -#endif } else - retval = kmalloc (bytes, gfp_flags); - + retval = kmalloc(bytes, gfp_flags); +#endif return retval; } @@ -489,9 +483,14 @@ net2280_free_buffer ( ) { /* free memory into the right allocator */ #ifndef USE_KMALLOC - if (dma != DMA_ADDR_INVALID) - dma_free_coherent (ep->dev->pdev, bytes, dma); - else + if (dma != DMA_ADDR_INVALID) { + struct net2280_ep *ep; + + ep = container_of(_ep, struct net2280_ep, ep); + if (!_ep) + return; + dma_free_coherent(&ep->dev->pdev->dev, bytes, buf, dma); + } else #endif kfree (buf); } @@ -516,8 +515,9 @@ write_fifo (struct net2280_ep *ep, struc /* INVARIANT: fifo is currently empty. (testable) */ if (req) { - total = req->length - req->actual; buf = req->buf + req->actual; + prefetch (buf); + total = req->length - req->actual; } else { total = 0; buf = 0; @@ -615,6 +615,7 @@ read_fifo (struct net2280_ep *ep, struct /* never overflow the rx buffer. the fifo reads packets until * it sees a short one; we might not be ready for them all. */ + prefetchw (buf); count = readl (®s->ep_avail); tmp = req->req.length - req->req.actual; if (count > tmp) { diff -prauN linux-2.6.0-test7/drivers/usb/host/ohci-hcd.c wli-2.6.0-test7-bk5-36/drivers/usb/host/ohci-hcd.c --- linux-2.6.0-test7/drivers/usb/host/ohci-hcd.c 2003-10-08 12:24:01.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/host/ohci-hcd.c 2003-10-14 02:49:47.000000000 -0700 @@ -125,7 +125,7 @@ /*-------------------------------------------------------------------------*/ -static const char hcd_name [] = "ohci-hcd"; +static const char hcd_name [] = "ohci_hcd"; #include "ohci.h" diff -prauN linux-2.6.0-test7/drivers/usb/host/uhci-hcd.c wli-2.6.0-test7-bk5-36/drivers/usb/host/uhci-hcd.c --- linux-2.6.0-test7/drivers/usb/host/uhci-hcd.c 2003-10-08 12:24:43.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/host/uhci-hcd.c 2003-10-14 02:49:47.000000000 -0700 @@ -2518,7 +2518,7 @@ static int uhci_hcd_get_frame_number(str return uhci_get_current_frame_number(hcd_to_uhci(hcd)); } -static const char hcd_name[] = "uhci-hcd"; +static const char hcd_name[] = "uhci_hcd"; static const struct hc_driver uhci_driver = { .description = hcd_name, diff -prauN linux-2.6.0-test7/drivers/usb/misc/Kconfig wli-2.6.0-test7-bk5-36/drivers/usb/misc/Kconfig --- linux-2.6.0-test7/drivers/usb/misc/Kconfig 2003-10-08 12:24:51.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/misc/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -15,7 +15,7 @@ config USB_EMI26 USB Audio driver. To compile this driver as a module, choose M here: the - module will be called audio. + module will be called emi26. config USB_TIGL tristate "Texas Instruments Graph Link USB (aka SilverLink) cable support" diff -prauN linux-2.6.0-test7/drivers/usb/serial/visor.c wli-2.6.0-test7-bk5-36/drivers/usb/serial/visor.c --- linux-2.6.0-test7/drivers/usb/serial/visor.c 2003-10-08 12:24:03.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/serial/visor.c 2003-10-14 02:49:47.000000000 -0700 @@ -201,6 +201,8 @@ static struct usb_device_id id_table [] .driver_info = (kernel_ulong_t)&palm_os_3_probe }, { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID), @@ -247,6 +249,7 @@ static struct usb_device_id clie_id_3_5_ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, + { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, diff -prauN linux-2.6.0-test7/drivers/usb/serial/visor.h wli-2.6.0-test7-bk5-36/drivers/usb/serial/visor.h --- linux-2.6.0-test7/drivers/usb/serial/visor.h 2003-10-08 12:24:27.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/serial/visor.h 2003-10-14 02:49:47.000000000 -0700 @@ -20,6 +20,7 @@ #define HANDSPRING_VENDOR_ID 0x082d #define HANDSPRING_VISOR_ID 0x0100 #define HANDSPRING_TREO_ID 0x0200 +#define HANDSPRING_TREO600_ID 0x0300 #define PALM_VENDOR_ID 0x0830 #define PALM_M500_ID 0x0001 diff -prauN linux-2.6.0-test7/drivers/usb/storage/Kconfig wli-2.6.0-test7-bk5-36/drivers/usb/storage/Kconfig --- linux-2.6.0-test7/drivers/usb/storage/Kconfig 2003-10-08 12:24:50.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/usb/storage/Kconfig 2003-10-14 02:49:47.000000000 -0700 @@ -41,7 +41,7 @@ config USB_STORAGE_FREECOM config USB_STORAGE_ISD200 bool "ISD-200 USB/ATA Bridge support" - depends on USB_STORAGE + depends on USB_STORAGE && BLK_DEV_IDE ---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 -prauN linux-2.6.0-test7/drivers/video/aty/aty128fb.c wli-2.6.0-test7-bk5-36/drivers/video/aty/aty128fb.c --- linux-2.6.0-test7/drivers/video/aty/aty128fb.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/video/aty/aty128fb.c 2003-10-14 02:49:47.000000000 -0700 @@ -2041,9 +2041,9 @@ aty128fb_setcolreg(u_int regno, u_int re #define ATY_MIRROR_CRT_ON 0x00000002 /* out param: u32* backlight value: 0 to 15 */ -#define FBIO_ATY128_GET_MIRROR _IOR('@', 1, sizeof(__u32*)) +#define FBIO_ATY128_GET_MIRROR _IOR('@', 1, __u32*) /* in param: u32* backlight value: 0 to 15 */ -#define FBIO_ATY128_SET_MIRROR _IOW('@', 2, sizeof(__u32*)) +#define FBIO_ATY128_SET_MIRROR _IOW('@', 2, __u32*) static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, struct fb_info *info) diff -prauN linux-2.6.0-test7/drivers/video/imsttfb.c wli-2.6.0-test7-bk5-36/drivers/video/imsttfb.c --- linux-2.6.0-test7/drivers/video/imsttfb.c 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/video/imsttfb.c 2003-10-14 02:49:47.000000000 -0700 @@ -1461,6 +1461,15 @@ imsttfb_probe(struct pci_dev *pdev, cons unsigned long addr, size; struct imstt_par *par; struct fb_info *info; +#ifdef CONFIG_PPC_OF + struct device_node *dp; + + dp = pci_device_to_OF_node(pdev); + if(dp) + printk(KERN_INFO "%s: OF name %s\n",__FUNCTION__, dp->name); + else + printk(KERN_ERR "imsttfb: no OF node for pci device\n"); +#endif /* CONFIG_PPC_OF */ size = sizeof(struct fb_info) + sizeof(struct imstt_par) + sizeof(u32) * 16; @@ -1488,6 +1497,11 @@ imsttfb_probe(struct pci_dev *pdev, cons switch (pdev->device) { case PCI_DEVICE_ID_IMS_TT128: /* IMS,tt128mbA */ par->ramdac = IBM; +#ifdef CONFIG_PPC_OF + if (dp && ((strcmp(dp->name, "IMS,tt128mb8") == 0) || + (strcmp(dp->name, "IMS,tt128mb8A") == 0))) + par->ramdac = TVP; +#endif /* CONFIG_PPC_OF */ break; case PCI_DEVICE_ID_IMS_TT3D: /* IMS,tt3d */ par->ramdac = TVP; diff -prauN linux-2.6.0-test7/drivers/video/matrox/matroxfb_base.h wli-2.6.0-test7-bk5-36/drivers/video/matrox/matroxfb_base.h --- linux-2.6.0-test7/drivers/video/matrox/matroxfb_base.h 2003-10-08 12:24:05.000000000 -0700 +++ wli-2.6.0-test7-bk5-36/drivers/video/matrox/matroxfb_base.h 2003-10-14 02:49:47.000000000 -0700 @@ -55,7 +55,7 @@ #if defined(CONFIG_PPC_PMAC) #include #include -#include