## Automatically generated incremental diff ## From: linux-2.6.7-rc3 ## To: linux-2.6.7 ## Robot: $Id: make-incremental-diff,v 1.12 2004/01/06 07:19:36 hpa Exp $ diff -urN linux-2.6.7-rc3/Documentation/arm/memory.txt linux-2.6.7/Documentation/arm/memory.txt --- linux-2.6.7-rc3/Documentation/arm/memory.txt 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/Documentation/arm/memory.txt 2004-06-15 23:10:23.514853872 -0700 @@ -1,7 +1,7 @@ Kernel Memory Layout on ARM Linux Russell King - April 27, 2003 (2.5.68) + May 21, 2004 (2.6.6) This document describes the virtual memory layout which the Linux kernel uses for ARM processors. It indicates which regions are @@ -29,32 +29,30 @@ CPU supports vector relocation (control register V bit.) -ffe00000 fffeffff Free for platform use, not recommended. +ffc00000 fffeffff DMA memory mapping region. Memory returned + by the dma_alloc_xxx functions will be + dynamically mapped here. -ffc00000 ffdfffff 2MB consistent memory mapping. - Memory returned by the consistent_alloc - low level function will be dynamically - mapped here. +ff000000 ffbfffff Reserved for future expansion of DMA + mapping region. -ff000000 ffbfffff Free for platform use, not recommended. +VMALLOC_END feffffff Free for platform use, recommended. -VMALLOC_END ff000000 Free for platform use, recommended. - -VMALLOC_START VMALLOC_END vmalloc() / ioremap() space. +VMALLOC_START VMALLOC_END-1 vmalloc() / ioremap() space. Memory returned by vmalloc/ioremap will be dynamically placed in this region. VMALLOC_START may be based upon the value of the high_memory variable. -PAGE_OFFSET high_memory Kernel direct-mapped RAM region. +PAGE_OFFSET high_memory-1 Kernel direct-mapped RAM region. This maps the platforms RAM, and typically maps all platform RAM in a 1:1 relationship. -TASK_SIZE PAGE_OFFSET Kernel module space +TASK_SIZE PAGE_OFFSET-1 Kernel module space Kernel modules inserted via insmod are placed here using dynamic mappings. -00001000 TASK_SIZE User space mappings +00001000 TASK_SIZE-1 User space mappings Per-thread mappings are placed here via the mmap() system call. diff -urN linux-2.6.7-rc3/Documentation/cpu-freq/amd-powernow.txt linux-2.6.7/Documentation/cpu-freq/amd-powernow.txt --- linux-2.6.7-rc3/Documentation/cpu-freq/amd-powernow.txt 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/Documentation/cpu-freq/amd-powernow.txt 2004-06-15 23:10:23.515853915 -0700 @@ -0,0 +1,38 @@ + +PowerNow! and Cool'n'Quiet are AMD names for frequency +management capabilities in AMD processors. As the hardware +implementation changes in new generations of the processors, +there is a different cpu-freq driver for each generation. + +Note that the driver's will not load on the "wrong" hardware, +so it is safe to try each driver in turn when in doubt as to +which is the correct driver. + +Note that the functionality to change frequency (and voltage) +is not available in all processors. The drivers will refuse +to load on processors without this capability. The capability +is detected with the cpuid instruction. + +The drivers use BIOS supplied tables to obtain frequency and +voltage information appropriate for a particular platform. +Frequency transitions will be unavailable if the BIOS does +not supply these tables. + +6th Generation: powernow-k6 + +7th Generation: powernow-k7: Athlon, Duron, Geode. + +8th Generation: powernow-k8: Athlon, Athlon 64, Opteron, Sempron. +Documentation on this functionality in 8th generation processors +is available in the "BIOS and Kernel Developer's Guide", publication +26094, in chapter 9, available for download from www.amd.com. + +BIOS supplied data, for powernow-k7 and for powernow-k8, may be +from either the PSB table or from ACPI objects. The ACPI support +is only available if the kernel config sets CONFIG_ACPI_PROCESSOR. +The powernow-k8 driver will attempt to use ACPI if so configured, +and fall back to PST if that fails. +The powernow-k7 driver will try to use the PSB support first, and +fall back to ACPI if the PSB support fails. A module parameter, +acpi_force, is provided to force ACPI support to be used instead +of PSB support. diff -urN linux-2.6.7-rc3/Documentation/fb/framebuffer.txt linux-2.6.7/Documentation/fb/framebuffer.txt --- linux-2.6.7-rc3/Documentation/fb/framebuffer.txt 2004-05-09 19:32:39.000000000 -0700 +++ linux-2.6.7/Documentation/fb/framebuffer.txt 2004-06-15 23:10:23.516853957 -0700 @@ -190,7 +190,7 @@ 1/(32.141E-6 s) = 31.113E3 Hz A full screen counts 480 (yres) lines, but we have to consider the vertical -retrace too (e.g. 49 `pixels'). So a full screen will take +retrace too (e.g. 49 `lines'). So a full screen will take (480+49)*32.141E-6 s = 17.002E-3 s diff -urN linux-2.6.7-rc3/Documentation/filesystems/Locking linux-2.6.7/Documentation/filesystems/Locking --- linux-2.6.7-rc3/Documentation/filesystems/Locking 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/Documentation/filesystems/Locking 2004-06-15 23:10:23.518854041 -0700 @@ -203,20 +203,34 @@ 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. +against the page the filesystem should redirty the page with +redirty_page_for_writepage(), 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 in-progress I/O and then start new I/O. The filesystem should unlock the page synchronously, before returning -to the caller. If the page has write I/O underway against it, -writepage() should run SetPageWriteback() against the page prior to -unlocking it. The write I/O completion handler should run -end_page_writeback() against the page. +to the caller. -That is: after 2.5.12, pages which are under writeout are *not* locked. +Unless the filesystem is going to redirty_page_for_writepage(), unlock the page +and return zero, writepage *must* run set_page_writeback() against the page, +followed by unlocking it. Once set_page_writeback() has been run against the +page, write I/O can be submitted and the write I/O completion handler must run +end_page_writeback() once the I/O is complete. If no I/O is submitted, the +filesystem must run end_page_writeback() against the page before returning from +writepage. + +That is: after 2.5.12, pages which are under writeout are *not* locked. Note, +if the filesystem needs the page to be locked during writeout, that is ok, too, +the page is allowed to be unlocked at any point in time between the calls to +set_page_writeback() and end_page_writeback(). + +Note, failure to run either redirty_page_for_writepage() or the combination of +set_page_writeback()/end_page_writeback() on a page submitted to writepage +will leave the page itself marked clean but it will be tagged as dirty in the +radix tree. This incoherency can lead to all sorts of hard-to-debug problems +in the filesystem like having dirty inodes at umount and losing written data. ->sync_page() locking rules are not well-defined - usually it is called with lock on page, but that is not guaranteed. Considering the currently diff -urN linux-2.6.7-rc3/Documentation/filesystems/ntfs.txt linux-2.6.7/Documentation/filesystems/ntfs.txt --- linux-2.6.7-rc3/Documentation/filesystems/ntfs.txt 2004-06-15 23:09:59.820856487 -0700 +++ linux-2.6.7/Documentation/filesystems/ntfs.txt 2004-06-15 23:10:23.518854041 -0700 @@ -273,6 +273,21 @@ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.14: + - Fix an NFSd caused deadlock reported by several users. +2.1.13: + - Implement writing of inodes (access time updates are not implemented + yet so mounting with -o noatime,nodiratime is enforced). + - Enable writing out of resident files so you can now overwrite any + uncompressed, unencrypted, nonsparse file as long as you do not + change the file size. + - Add housekeeping of ntfs system files so that ntfsfix no longer needs + to be run after writing to an NTFS volume. + NOTE: This still leaves quota tracking and user space journalling on + the side but they should not cause data corruption. In the worst + case the charged quotas will be out of date ($Quota) and some + userspace applications might get confused due to the out of date + userspace journal ($UsnJrnl). 2.1.12: - Fix the second fix to the decompression engine from the 2.1.9 release and some further internals cleanups. diff -urN linux-2.6.7-rc3/Documentation/networking/packet_mmap.txt linux-2.6.7/Documentation/networking/packet_mmap.txt --- linux-2.6.7-rc3/Documentation/networking/packet_mmap.txt 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/Documentation/networking/packet_mmap.txt 2004-06-15 23:10:23.526854378 -0700 @@ -1,11 +1,3 @@ - -DaveM: - -If you agree with it I will send two small patches to modify -kernel's configure help. - - Ulisses - -------------------------------------------------------------------------------- + ABSTRACT -------------------------------------------------------------------------------- @@ -405,8 +397,3 @@ Jesse Brandeburg, for fixing my grammathical/spelling errors ->>> EOF -- -To unsubscribe from this list: send the line "unsubscribe linux-net" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file diff -urN linux-2.6.7-rc3/MAINTAINERS linux-2.6.7/MAINTAINERS --- linux-2.6.7-rc3/MAINTAINERS 2004-06-15 23:09:59.957862253 -0700 +++ linux-2.6.7/MAINTAINERS 2004-06-15 23:10:23.539854925 -0700 @@ -1390,8 +1390,6 @@ NCP FILESYSTEM P: Petr Vandrovec M: vandrove@vc.cvut.cz -P: Volker Lendecke -M: vl@kki.org L: linware@sh.cvut.cz S: Maintained diff -urN linux-2.6.7-rc3/Makefile linux-2.6.7/Makefile --- linux-2.6.7-rc3/Makefile 2004-06-15 23:09:59.958862295 -0700 +++ linux-2.6.7/Makefile 2004-06-15 23:10:23.540854967 -0700 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 7 -EXTRAVERSION =-rc3 +EXTRAVERSION = NAME=Zonked Quokka # *DOCUMENTATION* @@ -1062,6 +1062,7 @@ buildcheck: $(PERL) scripts/reference_discarded.pl + $(PERL) scripts/reference_init.pl endif #ifeq ($(config-targets),1) endif #ifeq ($(mixed-targets),1) diff -urN linux-2.6.7-rc3/arch/arm/Kconfig linux-2.6.7/arch/arm/Kconfig --- linux-2.6.7-rc3/arch/arm/Kconfig 2004-06-15 23:09:59.976863053 -0700 +++ linux-2.6.7/arch/arm/Kconfig 2004-06-15 23:10:23.558855725 -0700 @@ -581,7 +581,7 @@ config ALIGNMENT_TRAP bool depends on CPU_32 - default y + default y if !ARCH_EBSA110 help ARM processors can not fetch/store information which is not naturally aligned on the bus, i.e., a 4 byte fetch must start at an diff -urN linux-2.6.7-rc3/arch/arm/boot/compressed/head.S linux-2.6.7/arch/arm/boot/compressed/head.S --- linux-2.6.7-rc3/arch/arm/boot/compressed/head.S 2004-06-15 23:09:59.977863095 -0700 +++ linux-2.6.7/arch/arm/boot/compressed/head.S 2004-06-15 23:10:23.559855767 -0700 @@ -86,6 +86,20 @@ .macro writeb, rb strb \rb, [r3, #0] .endm +#elif defined(CONFIG_ARCH_OMAP) + .macro loadsp, rb + mov \rb, #0xff000000 @ physical base address + add \rb, \rb, #0x00fb0000 +#if defined(CONFIG_OMAP_LL_DEBUG_UART2) || defined(CONFIG_OMAP_LL_DEBUG_UART3) + add \rb, \rb, #0x00000800 +#endif +#ifdef CONFIG_OMAP_LL_DEBUG_UART3 + add \rb, \rb, #0x00009000 +#endif + .endm + .macro writeb, rb + strb \rb, [r3] + .endm #else #error no serial architecture defined #endif diff -urN linux-2.6.7-rc3/arch/arm/configs/ebsa110_defconfig linux-2.6.7/arch/arm/configs/ebsa110_defconfig --- linux-2.6.7-rc3/arch/arm/configs/ebsa110_defconfig 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/arch/arm/configs/ebsa110_defconfig 2004-06-15 23:10:23.561855851 -0700 @@ -2,137 +2,120 @@ # 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_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_HOTPLUG=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=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_ARCA5K is not set +# CONFIG_ARCH_ADIFCC is not set # CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set CONFIG_ARCH_EBSA110=y -# CONFIG_ARCH_L7200 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_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set # -# Archimedes/A5000 Implementations -# - -# -# Archimedes/A5000 Implementations (select only ONE) -# -# 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 - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_ASSABET_NEPONSET is not set -# CONFIG_SA1100_BRUTUS is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_BITSY is not set -# CONFIG_SA1100_EXTENEX1 is not set -# CONFIG_SA1100_FREEBIRD is not set -# CONFIG_SA1100_GRAPHICSCLIENT is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HUW_WEBPANEL is not set -# CONFIG_SA1100_ITSY is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_NANOENGINE is not set -# CONFIG_SA1100_OMNIMETER is not set -# CONFIG_SA1100_PANGOLIN is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHERMAN 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 - -# -# CLPS711X/EP721X Implementations +# Processor Type # -# CONFIG_ARCH_P720T 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_SA110=y +CONFIG_CPU_32v4=y +CONFIG_CPU_ABRT_EV4=y +CONFIG_CPU_CACHE_V4WB=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WB=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=y -# CONFIG_CPU_SA1100 is not set -# CONFIG_DISCONTIGMEM is not set # # General setup # -# CONFIG_PCI is not set CONFIG_ISA=y -# CONFIG_ISA_DMA is not set -CONFIG_HOTPLUG=y +# CONFIG_ZBOOT_ROM is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 # # PCMCIA/CardBus support # CONFIG_PCMCIA=m -CONFIG_I82365=y +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_I82365=m # CONFIG_TCIC is not set -# CONFIG_PCMCIA_CLPS6700 is not set -# CONFIG_PCMCIA_SA1100 is not set -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y +CONFIG_PCMCIA_PROBE=y + +# +# At least one math emulation must be selected +# CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set CONFIG_FPE_FASTFPE=y -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_FW_LOADER is not set # CONFIG_PM is not set +# CONFIG_PREEMPT is not set # CONFIG_ARTHUR is not set CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8" CONFIG_LEDS=y @@ -143,22 +126,18 @@ # CONFIG_PARPORT=y CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_CML1=y CONFIG_PARPORT_PC_FIFO=y # CONFIG_PARPORT_PC_SUPERIO is not set # CONFIG_PARPORT_PC_PCMCIA is not set # CONFIG_PARPORT_ARC is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_SUNBPP is not set # CONFIG_PARPORT_OTHER is not set CONFIG_PARPORT_1284=y # -# Plug and Play configuration +# Plug and Play support # # CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices @@ -166,9 +145,6 @@ # 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 @@ -179,37 +155,29 @@ # 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=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y # CONFIG_NETLINK_DEV is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_RTNETLINK=y -CONFIG_NETLINK=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_FWMARK=y CONFIG_IP_ROUTE_NAT=y # CONFIG_IP_ROUTE_MULTIPATH is not set # CONFIG_IP_ROUTE_TOS is not set CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_ROUTE_LARGE_TABLES is not set CONFIG_IP_PNP=y # CONFIG_IP_PNP_DHCP is not set CONFIG_IP_PNP_BOOTP=y @@ -218,64 +186,113 @@ # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE 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 + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # -# IP: Netfilter Configuration +# IP: Netfilter Configuration # CONFIG_IP_NF_CONNTRACK=y CONFIG_IP_NF_FTP=y CONFIG_IP_NF_IRC=y +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set # CONFIG_IP_NF_QUEUE is not set CONFIG_IP_NF_IPTABLES=y CONFIG_IP_NF_MATCH_LIMIT=y -# CONFIG_IP_NF_MATCH_MAC is not set +CONFIG_IP_NF_MATCH_IPRANGE=y +CONFIG_IP_NF_MATCH_MAC=y +CONFIG_IP_NF_MATCH_PKTTYPE=y CONFIG_IP_NF_MATCH_MARK=y CONFIG_IP_NF_MATCH_MULTIPORT=y CONFIG_IP_NF_MATCH_TOS=y -# CONFIG_IP_NF_MATCH_TCPMSS is not set +CONFIG_IP_NF_MATCH_RECENT=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_DSCP=y +CONFIG_IP_NF_MATCH_AH_ESP=y +CONFIG_IP_NF_MATCH_LENGTH=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_MATCH_TCPMSS=y +CONFIG_IP_NF_MATCH_HELPER=y CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_UNCLEAN=y +CONFIG_IP_NF_MATCH_CONNTRACK=y # CONFIG_IP_NF_MATCH_OWNER is not set CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y -# CONFIG_IP_NF_TARGET_MIRROR is not set CONFIG_IP_NF_NAT=y CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=y CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_SAME=y +# CONFIG_IP_NF_NAT_LOCAL is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set CONFIG_IP_NF_NAT_IRC=y CONFIG_IP_NF_NAT_FTP=y CONFIG_IP_NF_MANGLE=y CONFIG_IP_NF_TARGET_TOS=y +CONFIG_IP_NF_TARGET_ECN=y +CONFIG_IP_NF_TARGET_DSCP=y CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_CLASSIFY=y CONFIG_IP_NF_TARGET_LOG=y -# CONFIG_IP_NF_TARGET_TCPMSS is not set -CONFIG_IPV6=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=y +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_RAW is not set # -# IPv6: Netfilter Configuration +# IPv6: Netfilter Configuration # +# CONFIG_IP6_NF_QUEUE is not set CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_MATCH_LIMIT=y +CONFIG_IP6_NF_MATCH_MAC=y +CONFIG_IP6_NF_MATCH_RT=y +CONFIG_IP6_NF_MATCH_OPTS=y +CONFIG_IP6_NF_MATCH_FRAG=y +CONFIG_IP6_NF_MATCH_HL=y +CONFIG_IP6_NF_MATCH_MULTIPORT=y +# CONFIG_IP6_NF_MATCH_OWNER is not set CONFIG_IP6_NF_MATCH_MARK=y +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +CONFIG_IP6_NF_MATCH_AHESP=y +CONFIG_IP6_NF_MATCH_LENGTH=y +# CONFIG_IP6_NF_MATCH_EUI64 is not set CONFIG_IP6_NF_FILTER=y +# CONFIG_IP6_NF_TARGET_LOG is not set CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_TARGET_MARK=y -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_IP6_NF_RAW is not set # -# +# SCTP Configuration (EXPERIMENTAL) # +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_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 @@ -288,25 +305,30 @@ # CONFIG_NET_SCHED is not set # -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set # # ARCnet devices # # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set CONFIG_ARM_AM79C961A=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -322,40 +344,20 @@ # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC 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 -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set # -# Wireless LAN (non-hamradio) +# Ethernet (10000 Mbit) # -# CONFIG_NET_RADIO is not set # # Token Ring devices # # CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set # -# Wan interfaces +# Wireless LAN (non-hamradio) # -# CONFIG_WAN is not set +# CONFIG_NET_RADIO is not set # # PCMCIA network device support @@ -368,39 +370,42 @@ # CONFIG_PCMCIA_NMCLAN is not set # CONFIG_PCMCIA_SMC91C92 is not set # CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_ARCNET_COM20020_CS is not set -# CONFIG_PCMCIA_IBMTR is not set -# CONFIG_NET_PCMCIA_RADIO is not set +# CONFIG_PCMCIA_AXNET is not set # -# Amateur Radio support +# Wan interfaces # -# CONFIG_HAMRADIO is not set +# CONFIG_WAN is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # -# IrDA (infrared) support +# SCSI device support # -# CONFIG_IRDA is not set +# CONFIG_SCSI is not set # -# ATA/IDE/MFM/RLL support +# Fusion MPT device support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# IEEE 1394 (FireWire) support # -# CONFIG_SCSI is not set +# CONFIG_IEEE1394 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 @@ -408,76 +413,80 @@ # CONFIG_ISDN is not set # -# Input core support +# Input device support # # CONFIG_INPUT is not set # -# Character devices +# Userland interfaces # -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -# CONFIG_SERIAL_MANY_PORTS is not set -# CONFIG_SERIAL_SHARE_IRQ is not set -# CONFIG_SERIAL_DETECT_IRQ is not set -# CONFIG_SERIAL_MULTIPORT is not set -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD 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_SA1100 is not set -# CONFIG_SERIAL_SA1100_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_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -# CONFIG_PPDEV is not set # -# I2C support +# Input I/O drivers # -# CONFIG_I2C is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set +# CONFIG_SERIO_I8042 is not set # -# Mice +# Input Device Drivers # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# Character devices # -# CONFIG_JOYSTICK is not set +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set # -# Input core support is needed for joysticks +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + # +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # CONFIG_QIC02_TAPE is not set # +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# # Watchdog Cards # CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# CONFIG_SOFT_WATCHDOG=y -# CONFIG_WDT is not set -# CONFIG_WDTPCI is not set + +# +# ISA-based Watchdog Cards +# # CONFIG_PCWATCHDOG is not set -# CONFIG_ACQUIRE_WDT is not set -# CONFIG_ADVANTECH_WDT is not set -# CONFIG_60XX_WDT is not set # CONFIG_MIXCOMWD is not set -# CONFIG_MACHZ_WDT is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_WDT is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -492,7 +501,13 @@ # # PCMCIA character devices # -# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set # # Multimedia devices @@ -500,73 +515,83 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +CONFIG_MINIX_FS=y +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# 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_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS 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 is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -CONFIG_MINIX_FS=y # CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW 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 is not set # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set -# CONFIG_UDF_FS is not set -# 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_NFS_FS=y -# CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 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_AFS_FS is not set # # Partition Types @@ -578,26 +603,68 @@ # CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# # CONFIG_NLS is not set # +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# Misc devices +# + +# # USB support # -# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # # Kernel hacking # CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_NO_PGT_CACHE is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_DEBUG_DC21285_PORT is not set -# CONFIG_DEBUG_CLPS711X_UART2 is not set +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -urN linux-2.6.7-rc3/arch/arm/configs/lpd7a400_defconfig linux-2.6.7/arch/arm/configs/lpd7a400_defconfig --- linux-2.6.7-rc3/arch/arm/configs/lpd7a400_defconfig 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/arch/arm/configs/lpd7a400_defconfig 2004-06-15 23:10:23.563855935 -0700 @@ -19,19 +19,23 @@ # # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_FUTEX=y # CONFIG_EPOLL is not set CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # @@ -43,21 +47,24 @@ # System Type # # CONFIG_ARCH_ADIFCC is not set -# CONFIG_ARCH_ANAKIN 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_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set # CONFIG_ARCH_SHARK is not set CONFIG_ARCH_LH7A40X=y +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set # # CLPS711X/EP721X Implementations @@ -82,7 +89,19 @@ # # -# Intel PXA250/210 Implementations +# Intel IXP4xx Implementation Options +# + +# +# IXP4xx Platforms +# + +# +# IXP4xx Options +# + +# +# Intel PXA2xx Implementations # # @@ -90,6 +109,26 @@ # # +# TI OMAP Implementations +# + +# +# OMAP Core Type +# + +# +# OMAP Board Type +# + +# +# OMAP Feature Selections +# + +# +# S3C2410 Implementations +# + +# # LH7A40X Implementations # # CONFIG_MACH_KEV7A400 is not set @@ -254,23 +293,21 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 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_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -291,6 +328,11 @@ # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -311,38 +353,24 @@ # # Ethernet (10000 Mbit) # -# CONFIG_PPP is not set -# CONFIG_SLIP is not set # -# Wireless LAN (non-hamradio) +# Token Ring devices # -# CONFIG_NET_RADIO is not set # -# Token Ring devices +# Wireless LAN (non-hamradio) # -# CONFIG_SHAPER is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces # # CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # # ATA/ATAPI/MFM/RLL support @@ -367,9 +395,9 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +CONFIG_IDE_ARM=y # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set -# CONFIG_DMA_NONPCI is not set # CONFIG_BLK_DEV_HD is not set # @@ -452,11 +480,6 @@ CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# Mice -# -# CONFIG_BUSMOUSE is not set # CONFIG_QIC02_TAPE is not set # @@ -536,6 +559,7 @@ # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y @@ -576,7 +600,7 @@ CONFIG_LOCKD_V4=y # CONFIG_EXPORTFS is not set CONFIG_SUNRPC=y -# CONFIG_SUNRPC_GSS is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set @@ -665,6 +689,11 @@ CONFIG_DUMMY_CONSOLE=y # +# Sound +# +# CONFIG_SOUND is not set + +# # Misc devices # @@ -706,5 +735,6 @@ # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.6.7-rc3/arch/arm/configs/lpd7a404_defconfig linux-2.6.7/arch/arm/configs/lpd7a404_defconfig --- linux-2.6.7-rc3/arch/arm/configs/lpd7a404_defconfig 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/arch/arm/configs/lpd7a404_defconfig 2004-06-15 23:10:23.564855977 -0700 @@ -19,19 +19,23 @@ # # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_HOTPLUG is not set CONFIG_IKCONFIG=y # CONFIG_IKCONFIG_PROC is not set CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set CONFIG_FUTEX=y # CONFIG_EPOLL is not set CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set +CONFIG_IOSCHED_CFQ=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # @@ -46,19 +50,21 @@ # 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_IXP4XX is not set # CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_SHARK is not set CONFIG_ARCH_LH7A40X=y +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE_PB is not set # # CLPS711X/EP721X Implementations @@ -83,7 +89,19 @@ # # -# Intel PXA250/210 Implementations +# Intel IXP4xx Implementation Options +# + +# +# IXP4xx Platforms +# + +# +# IXP4xx Options +# + +# +# Intel PXA2xx Implementations # # @@ -95,6 +113,14 @@ # # +# OMAP Core Type +# + +# +# OMAP Board Type +# + +# # OMAP Feature Selections # @@ -271,8 +297,6 @@ # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set # CONFIG_NETFILTER is not set # @@ -280,7 +304,9 @@ # # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -301,6 +327,11 @@ # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -321,41 +352,24 @@ # # Ethernet (10000 Mbit) # -# CONFIG_PPP is not set -# CONFIG_SLIP is not set # -# Wireless LAN (non-hamradio) +# Token Ring devices # -# CONFIG_NET_RADIO is not set # -# Token Ring devices +# Wireless LAN (non-hamradio) # -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces # # CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# Bluetooth support -# -# CONFIG_BT is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # # ATA/ATAPI/MFM/RLL support @@ -381,6 +395,7 @@ # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +CONFIG_IDE_ARM=y # CONFIG_BLK_DEV_IDEDMA is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -404,7 +419,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -418,6 +432,7 @@ # SCSI low-level drivers # # CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_DEBUG is not set @@ -573,6 +588,7 @@ # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y @@ -618,7 +634,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -761,6 +776,7 @@ # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -809,6 +825,8 @@ # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_TEST is not set # @@ -845,5 +863,6 @@ # Library routines # CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y diff -urN linux-2.6.7-rc3/arch/arm/kernel/signal.c linux-2.6.7/arch/arm/kernel/signal.c --- linux-2.6.7-rc3/arch/arm/kernel/signal.c 2004-06-15 23:09:59.987863516 -0700 +++ linux-2.6.7/arch/arm/kernel/signal.c 2004-06-15 23:10:23.572856314 -0700 @@ -253,6 +253,9 @@ if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) + goto badframe; + /* Send SIGTRAP if we're single-stepping */ if (current->ptrace & PT_SINGLESTEP) { ptrace_cancel_bpt(current); @@ -402,6 +405,7 @@ sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); + stack_t stack; int err = 0; if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) @@ -411,8 +415,14 @@ __put_user_error(&frame->uc, &frame->puc, err); err |= copy_siginfo_to_user(&frame->info, info); - /* Clear all the bits of the ucontext we don't use. */ - err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); + __put_user_error(0, &frame->uc.uc_flags, err); + __put_user_error(NULL, &frame->uc.uc_link, err); + + memset(&stack, 0, sizeof(stack)); + stack.ss_sp = (void *)current->sas_ss_sp; + stack.ss_flags = sas_ss_flags(regs->ARM_sp); + stack.ss_size = current->sas_ss_size; + err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/ regs, set->sig[0]); diff -urN linux-2.6.7-rc3/arch/arm/lib/Makefile linux-2.6.7/arch/arm/lib/Makefile --- linux-2.6.7-rc3/arch/arm/lib/Makefile 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/arm/lib/Makefile 2004-06-15 23:10:23.573856356 -0700 @@ -24,7 +24,6 @@ lib-$(CONFIG_ARCH_CLPS7500) += io-acorn.o lib-$(CONFIG_ARCH_L7200) += io-acorn.o lib-$(CONFIG_ARCH_SHARK) += io-shark.o -lib-$(CONFIG_ARCH_CLPS711X) += io-acorn.o $(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S diff -urN linux-2.6.7-rc3/arch/arm/lib/io-acorn.S linux-2.6.7/arch/arm/lib/io-acorn.S --- linux-2.6.7-rc3/arch/arm/lib/io-acorn.S 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/arch/arm/lib/io-acorn.S 2004-06-15 23:10:23.573856356 -0700 @@ -17,31 +17,6 @@ .text .align - .equ diff_pcio_base, PCIO_BASE - IO_BASE - - .macro outw2 rd - mov r8, \rd, lsl #16 - orr r8, r8, r8, lsr #16 - str r8, [r3, r0, lsl #2] - mov r8, \rd, lsr #16 - orr r8, r8, r8, lsl #16 - str r8, [r3, r0, lsl #2] - .endm - - .macro inw2 rd, mask, temp - ldr \rd, [r0] - and \rd, \rd, \mask - ldr \temp, [r0] - orr \rd, \rd, \temp, lsl #16 - .endm - - .macro addr rd - tst \rd, #0x80000000 - mov \rd, \rd, lsl #2 - add \rd, \rd, #IO_BASE - addeq \rd, \rd, #diff_pcio_base - .endm - .iosl_warning: .ascii "<4>insl/outsl not implemented, called from %08lX\0" .align diff -urN linux-2.6.7-rc3/arch/arm/mach-clps711x/Kconfig linux-2.6.7/arch/arm/mach-clps711x/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-clps711x/Kconfig 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-clps711x/Kconfig 2004-06-15 23:10:23.574856399 -0700 @@ -1,16 +1,15 @@ +if ARCH_CLPS711X menu "CLPS711X/EP721X Implementations" config ARCH_AUTCPU12 bool "AUTCPU12" - depends on ARCH_CLPS711X help Say Y if you intend to run the kernel on the autronix autcpu12 board. This board is based on a Cirrus Logic CS89712. config ARCH_CDB89712 bool "CDB89712" - depends on ARCH_CLPS711X help This is an evaluation board from Cirrus for the CS89712 processor. The board includes 2 serial ports, Ethernet, IRDA, and expansion @@ -18,32 +17,27 @@ config ARCH_CEIVA bool "CEIVA" - depends on ARCH_CLPS711X help Say Y here if you intend to run this kernel on the Ceiva/Polaroid PhotoMax Digital Picture Frame. config ARCH_CLEP7312 bool "CLEP7312" - depends on ARCH_CLPS711X config ARCH_EDB7211 bool "EDB7211" - depends on ARCH_CLPS711X help Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 evaluation board. config ARCH_P720T bool "P720T" - depends on ARCH_CLPS711X help Say Y here if you intend to run this kernel on the ARM Prospector 720T. config ARCH_FORTUNET bool "FORTUNET" - depends on ARCH_CLPS711X # XXX Maybe these should indicate register compatibility # instead of being mutually exclusive. @@ -74,3 +68,4 @@ endmenu +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-ebsa110/io.c linux-2.6.7/arch/arm/mach-ebsa110/io.c --- linux-2.6.7-rc3/arch/arm/mach-ebsa110/io.c 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-ebsa110/io.c 2004-06-15 23:10:23.575856441 -0700 @@ -67,9 +67,9 @@ u32 ret, a = __isamem_convert_addr(addr); if ((int)addr & 1) - ret = __raw_getl(a); + ret = __raw_readl(a); else - ret = __raw_getb(a); + ret = __raw_readb(a); return ret; } @@ -80,7 +80,7 @@ if ((int)addr & 1) BUG(); - return __raw_getw(a); + return __raw_readw(a); } u32 __readl(void *addr) @@ -90,8 +90,8 @@ if ((int)addr & 3) BUG(); - ret = __raw_getw(a); - ret |= __raw_getw(a + 4) << 16; + ret = __raw_readw(a); + ret |= __raw_readw(a + 4) << 16; return ret; } @@ -104,9 +104,9 @@ u32 a = __isamem_convert_addr(addr); if ((int)addr & 1) - __raw_putl(val, a); + __raw_writel(val, a); else - __raw_putb(val, a); + __raw_writeb(val, a); } void __writew(u16 val, void *addr) @@ -116,7 +116,7 @@ if ((int)addr & 1) BUG(); - __raw_putw(val, a); + __raw_writew(val, a); } void __writel(u32 val, void *addr) @@ -126,8 +126,8 @@ if ((int)addr & 3) BUG(); - __raw_putw(val, a); - __raw_putw(val >> 16, a + 4); + __raw_writew(val, a); + __raw_writew(val >> 16, a + 4); } EXPORT_SYMBOL(__writeb); @@ -147,7 +147,7 @@ * The SuperIO registers use sane addressing techniques... */ if (SUPERIO_PORT(port)) - ret = __raw_getb(ISAIO_BASE + (port << 2)); + ret = __raw_readb(ISAIO_BASE + (port << 2)); else { u32 a = ISAIO_BASE + ((port & ~1) << 1); @@ -155,9 +155,9 @@ * Shame nothing else does */ if (port & 1) - ret = __raw_getl(a); + ret = __raw_readl(a); else - ret = __raw_getb(a); + ret = __raw_readb(a); } return ret; } @@ -170,7 +170,7 @@ * The SuperIO registers use sane addressing techniques... */ if (SUPERIO_PORT(port)) - ret = __raw_getw(ISAIO_BASE + (port << 2)); + ret = __raw_readw(ISAIO_BASE + (port << 2)); else { u32 a = ISAIO_BASE + ((port & ~1) << 1); @@ -180,7 +180,7 @@ if (port & 1) BUG(); - ret = __raw_getw(a); + ret = __raw_readw(a); } return ret; } @@ -201,7 +201,7 @@ * The SuperIO registers use sane addressing techniques... */ if (SUPERIO_PORT(port)) - __raw_putb(val, ISAIO_BASE + (port << 2)); + __raw_writeb(val, ISAIO_BASE + (port << 2)); else { u32 a = ISAIO_BASE + ((port & ~1) << 1); @@ -209,9 +209,9 @@ * Shame nothing else does */ if (port & 1) - __raw_putl(val, a); + __raw_writel(val, a); else - __raw_putb(val, a); + __raw_writeb(val, a); } } @@ -230,7 +230,7 @@ BUG(); } - __raw_putw(val, ISAIO_BASE + off); + __raw_writew(val, ISAIO_BASE + off); } void __outl(u32 val, int port) diff -urN linux-2.6.7-rc3/arch/arm/mach-epxa10db/Kconfig linux-2.6.7/arch/arm/mach-epxa10db/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-epxa10db/Kconfig 2004-05-09 19:32:39.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-epxa10db/Kconfig 2004-06-15 23:10:23.575856441 -0700 @@ -1,17 +1,16 @@ +if ARCH_CAMELOT menu "Epxa10db" comment "PLD hotswap support" - depends on ARCH_CAMELOT config PLD bool - depends on ARCH_CAMELOT default y config PLD_HOTSWAP bool "Support for PLD device hotplugging (experimental)" - depends on ARCH_CAMELOT && EXPERIMENTAL + depends on EXPERIMENTAL help This enables support for the dynamic loading and configuration of compatible drivers when the contents of the PLD are changed. This @@ -21,3 +20,4 @@ endmenu +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-footbridge/Kconfig linux-2.6.7/arch/arm/mach-footbridge/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-footbridge/Kconfig 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-footbridge/Kconfig 2004-06-15 23:10:23.576856483 -0700 @@ -1,9 +1,9 @@ +if ARCH_FOOTBRIDGE menu "Footbridge Implementations" config ARCH_CATS bool "CATS" - depends on ARCH_FOOTBRIDGE help Say Y here if you intend to run this kernel on the CATS. @@ -11,7 +11,6 @@ config ARCH_PERSONAL_SERVER bool "Compaq Personal Server" - depends on ARCH_FOOTBRIDGE ---help--- Say Y here if you intend to run this kernel on the Compaq Personal Server. @@ -29,7 +28,6 @@ config ARCH_EBSA285_ADDIN bool "EBSA285 (addin mode)" - depends on ARCH_FOOTBRIDGE help Say Y here if you intend to run this kernel on the EBSA285 card in addin mode. @@ -38,7 +36,6 @@ config ARCH_EBSA285_HOST bool "EBSA285 (host mode)" - depends on ARCH_FOOTBRIDGE help Say Y here if you intend to run this kernel on the EBSA285 card in host ("central function") mode. @@ -47,7 +44,6 @@ config ARCH_NETWINDER bool "NetWinder" - depends on ARCH_FOOTBRIDGE help Say Y here if you intend to run this kernel on the Rebel.COM NetWinder. Information about this machine can be found at: @@ -58,3 +54,4 @@ endmenu +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-integrator/Kconfig linux-2.6.7/arch/arm/mach-integrator/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-integrator/Kconfig 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-integrator/Kconfig 2004-06-15 23:10:23.576856483 -0700 @@ -1,5 +1,6 @@ +if ARCH_INTEGRATOR + menu "Integrator Options" - depends on ARCH_INTEGRATOR config ARCH_INTEGRATOR_AP bool "Support Integrator/AP and Integrator/PP2 platforms" @@ -28,3 +29,5 @@ module will be called impd1. endmenu + +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-iop3xx/Kconfig linux-2.6.7/arch/arm/mach-iop3xx/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-iop3xx/Kconfig 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-iop3xx/Kconfig 2004-06-15 23:10:23.577856525 -0700 @@ -1,10 +1,10 @@ +if ARCH_IOP3XX menu "IOP3xx Implementation Options" choice prompt "IOP3xx System Type" default ARCH_IQ80310 - depends on ARCH_IOP3XX config ARCH_IQ80310 bool "IQ80310" @@ -36,19 +36,20 @@ config IOP3XX_AAU bool "Support Intel IOP3xx Application Accelerator Unit (EXPERIMENTAL)" - depends on ARCH_IOP3XX && EXPERIMENTAL + depends on EXPERIMENTAL config IOP3XX_DMA bool "Support Intel IOP3xx DMA (EXPERIMENTAL)" - depends on ARCH_IOP3XX && EXPERIMENTAL + depends on EXPERIMENTAL config IOP3XX_MU bool "Support Intel IOP3xx Messaging Unit (EXPERIMENTAL)" - depends on ARCH_IOP3XX && EXPERIMENTAL + depends on EXPERIMENTAL config IOP3XX_PMON bool "Support Intel IOP3xx Performance Monitor (EXPERIMENTAL)" - depends on ARCH_IOP3XX && EXPERIMENTAL + depends on EXPERIMENTAL endmenu +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-ixp4xx/Kconfig linux-2.6.7/arch/arm/mach-ixp4xx/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-ixp4xx/Kconfig 2004-06-15 23:09:59.991863684 -0700 +++ linux-2.6.7/arch/arm/mach-ixp4xx/Kconfig 2004-06-15 23:10:23.579856609 -0700 @@ -1,7 +1,7 @@ +if ARCH_IXP4XX config ARCH_SUPPORTS_BIG_ENDIAN bool - depends on ARCH_IXP4XX default y menu "Intel IXP4xx Implementation Options" @@ -10,7 +10,6 @@ config ARCH_AVILA bool "Avila" - depends on ARCH_IXP4XX help Say 'Y' here if you want your kernel to support the Gateworks Avila Network Platform. For more information on this platform, @@ -18,7 +17,6 @@ config ARCH_ADI_COYOTE bool "Coyote" - depends on ARCH_IXP4XX help Say 'Y' here if you want your kernel to support the ADI Engineering Coyote Gateway Reference Platform. For more @@ -26,7 +24,6 @@ config ARCH_IXDP425 bool "IXDP425" - depends on ARCH_IXP4XX help Say 'Y' here if you want your kernel to support Intel's IXDP425 Development Platform (Also known as Richfield). @@ -44,7 +41,6 @@ config ARCH_PRPMC1100 bool "PrPMC1100" - depends on ARCH_IXP4XX help Say 'Y' here if you want your kernel to support the Motorola PrPCM1100 Processor Mezanine Module. For more information on @@ -62,7 +58,6 @@ config IXP4XX_INDIRECT_PCI bool "Use indirect PCI memory access" - depends on ARCH_IXP4XX help IXP4xx provides two methods of accessing PCI memory space: @@ -87,3 +82,5 @@ what you need, leave this option unselected. endmenu + +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-lh7a40x/Kconfig linux-2.6.7/arch/arm/mach-lh7a40x/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-lh7a40x/Kconfig 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-lh7a40x/Kconfig 2004-06-15 23:10:23.584856820 -0700 @@ -1,9 +1,9 @@ +if ARCH_LH7A40X menu "LH7A40X Implementations" config MACH_KEV7A400 bool "KEV7A400" - depends on ARCH_LH7A40X select ARCH_LH7A400 help Say Y here if you are using the Sharp KEV7A400 development @@ -12,9 +12,8 @@ config MACH_LPD7A400 bool "LPD7A400 Card Engine" - depends on ARCH_LH7A40X select ARCH_LH7A400 - select IDE_POLL +# select IDE_POLL help Say Y here if you are using Logic Product Development's LPD7A400 CardEngine. For the time being, the LPD7A400 and @@ -22,9 +21,8 @@ config MACH_LPD7A404 bool "LPD7A404 Card Engine" - depends on ARCH_LH7A40X select ARCH_LH7A404 - select IDE_POLL +# select IDE_POLL help Say Y here if you are using Logic Product Development's LPD7A404 CardEngine. For the time being, the LPD7A400 and @@ -37,3 +35,5 @@ bool endmenu + +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-lh7a40x/arch-lpd7a40x.c linux-2.6.7/arch/arm/mach-lh7a40x/arch-lpd7a40x.c --- linux-2.6.7-rc3/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-lh7a40x/arch-lpd7a40x.c 2004-06-15 23:10:23.584856820 -0700 @@ -116,7 +116,12 @@ static void __init lpd7a40x_init (void) { - CPLD_CONTROL = 0x0; /* Enable LAN (Disable LCD) */ + CPLD_CONTROL |= (1<<6); /* Mask USB1 connection IRQ */ + CPLD_CONTROL &= ~(0 + | (1<<1) /* Disable LCD */ + | (1<<0) /* Enable WLAN */ + ); + platform_add_devices (lpd7a40x_devs, ARRAY_SIZE (lpd7a40x_devs)); } @@ -191,7 +196,7 @@ int pinCPLD = (cpld_version == 0x28) ? 7 : 3; #if defined CONFIG_MACH_LPD7A404 - cpld_version = 0x34; /* Override, for now */ + cpld_version = 0x34; /* Coerce LPD7A404 to RevB */ #endif /* First, configure user controlled GPIOF interrupts */ @@ -204,7 +209,7 @@ /* Then, configure CPLD interrupt */ - CPLD_INTERRUPTS = 0x0c; /* Disable all CPLD interrupts */ + CPLD_INTERRUPTS = 0x9c; /* Disable all CPLD interrupts */ GPIO_PFDD &= ~(1 << pinCPLD); /* Make input */ GPIO_INTTYPE1 |= (1 << pinCPLD); /* Edge triggered */ GPIO_INTTYPE2 &= ~(1 << pinCPLD); /* Active low */ diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/Kconfig linux-2.6.7/arch/arm/mach-omap/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-omap/Kconfig 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-omap/Kconfig 2004-06-15 23:10:23.584856820 -0700 @@ -1,27 +1,24 @@ +if ARCH_OMAP menu "TI OMAP Implementations" comment "OMAP Core Type" config ARCH_OMAP730 - depends on ARCH_OMAP bool "OMAP730 Based System" select CPU_ARM926T config ARCH_OMAP1510 - depends on ARCH_OMAP default y bool "OMAP1510 Based System" select CPU_ARM925T select CPU_DCACHE_WRITETHROUGH config ARCH_OMAP1610 - depends on ARCH_OMAP bool "OMAP1610 Based System" select CPU_ARM926T config ARCH_OMAP5912 - depends on ARCH_OMAP bool "OMAP5912 Based System" select CPU_ARM926T @@ -87,7 +84,6 @@ #config OMAP_BOOT_TAG # bool "OMAP bootloader information passing" -# depends on ARCH_OMAP # default n # help # Say Y, if you have a bootloader which passes information @@ -95,7 +91,6 @@ config OMAP_MUX bool "OMAP multiplexing support" - depends on ARCH_OMAP default y help Pin multiplexing support for OMAP boards. If your bootloader @@ -113,7 +108,6 @@ choice prompt "Low-level debug console UART" - depends on ARCH_OMAP default OMAP_LL_DEBUG_UART1 config OMAP_LL_DEBUG_UART1 @@ -171,3 +165,5 @@ Enable 30MHz clock for OMAP CPU. If unsure, say N. endmenu + +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/board-generic.c linux-2.6.7/arch/arm/mach-omap/board-generic.c --- linux-2.6.7-rc3/arch/arm/mach-omap/board-generic.c 2004-06-15 23:09:59.996863895 -0700 +++ linux-2.6.7/arch/arm/mach-omap/board-generic.c 2004-06-15 23:10:23.585856862 -0700 @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -64,7 +65,7 @@ omap_map_io(); } -MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610") +MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710") MAINTAINER("Tony Lindgren ") BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) BOOT_PARAMS(0x10000100) diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/board-innovator.c linux-2.6.7/arch/arm/mach-omap/board-innovator.c --- linux-2.6.7-rc3/arch/arm/mach-omap/board-innovator.c 2004-06-15 23:09:59.996863895 -0700 +++ linux-2.6.7/arch/arm/mach-omap/board-innovator.c 2004-06-15 23:10:23.585856862 -0700 @@ -19,8 +19,10 @@ #include #include #include +#include #include +#include #include #include @@ -36,14 +38,14 @@ /* Only FPGA needs to be mapped here. All others are done with ioremap */ static struct map_desc innovator1510_io_desc[] __initdata = { -{ OMAP1510P1_FPGA_BASE, OMAP1510P1_FPGA_START, OMAP1510P1_FPGA_SIZE, +{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE, MT_DEVICE }, }; static struct resource innovator1510_smc91x_resources[] = { [0] = { - .start = OMAP1510P1_FPGA_ETHR_START, /* Physical */ - .end = OMAP1510P1_FPGA_ETHR_START + 16, + .start = OMAP1510_FPGA_ETHR_START, /* Physical */ + .end = OMAP1510_FPGA_ETHR_START + 16, .flags = IORESOURCE_MEM, }, [1] = { @@ -132,12 +134,13 @@ #ifdef CONFIG_ARCH_OMAP1510 if (cpu_is_omap1510()) { iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); + udelay(10); /* Delay needed for FPGA */ /* Dump the Innovator FPGA rev early - useful info for support. */ printk("Innovator FPGA Rev %d.%d Board Rev %d\n", - fpga_read(OMAP1510P1_FPGA_REV_HIGH), - fpga_read(OMAP1510P1_FPGA_REV_LOW), - fpga_read(OMAP1510P1_FPGA_BOARD_REV)); + fpga_read(OMAP1510_FPGA_REV_HIGH), + fpga_read(OMAP1510_FPGA_REV_LOW), + fpga_read(OMAP1510_FPGA_BOARD_REV)); } #endif #ifdef CONFIG_ARCH_OMAP1610 diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/board-osk.c linux-2.6.7/arch/arm/mach-omap/board-osk.c --- linux-2.6.7-rc3/arch/arm/mach-omap/board-osk.c 2004-06-15 23:09:59.996863895 -0700 +++ linux-2.6.7/arch/arm/mach-omap/board-osk.c 2004-06-15 23:10:23.585856862 -0700 @@ -31,6 +31,7 @@ #include #include +#include #include #include diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/board-perseus2.c linux-2.6.7/arch/arm/mach-omap/board-perseus2.c --- linux-2.6.7-rc3/arch/arm/mach-omap/board-perseus2.c 2004-06-15 23:09:59.996863895 -0700 +++ linux-2.6.7/arch/arm/mach-omap/board-perseus2.c 2004-06-15 23:10:23.586856904 -0700 @@ -3,6 +3,9 @@ * * Modified from board-generic.c * + * Original OMAP730 support by Jean Pihet + * Updated for 2.6 by Kevin Hilman + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -13,6 +16,7 @@ #include #include +#include #include #include @@ -102,7 +106,7 @@ } MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") - MAINTAINER("Kevin Hilman ") + MAINTAINER("Kevin Hilman ") BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) BOOT_PARAMS(0x10000100) MAPIO(omap_perseus2_map_io) diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/bus.c linux-2.6.7/arch/arm/mach-omap/bus.c --- linux-2.6.7-rc3/arch/arm/mach-omap/bus.c 2004-06-15 23:09:59.997863937 -0700 +++ linux-2.6.7/arch/arm/mach-omap/bus.c 2004-06-15 23:10:23.586856904 -0700 @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -265,7 +266,7 @@ } } -module_init(omap_bus_init); +postcore_initcall(omap_bus_init); module_exit(omap_bus_exit); MODULE_DESCRIPTION("Virtual bus for OMAP"); diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/clocks.c linux-2.6.7/arch/arm/mach-omap/clocks.c --- linux-2.6.7-rc3/arch/arm/mach-omap/clocks.c 2004-05-09 19:32:37.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-omap/clocks.c 2004-06-15 23:10:23.587856946 -0700 @@ -84,7 +84,7 @@ }, { .name = "ck_gen1", .flags = CK_RATEF | CK_IDLEF, - .rate_reg = CK_DPLL1, + .rate_reg = DPLL_CTL, .idle_reg = ARM_IDLECT1, .idle_shift = IDLDPLL_ARM, .parent = OMAP_CLKIN, @@ -629,39 +629,39 @@ omap_writew(0x1000, ARM_SYSST); #if defined(CONFIG_OMAP_ARM_30MHZ) omap_writew(0x1555, ARM_CKCTL); - omap_writew(0x2290, DPLL_CTL_REG); + omap_writew(0x2290, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_60MHZ) omap_writew(0x1005, ARM_CKCTL); - omap_writew(0x2290, DPLL_CTL_REG); + omap_writew(0x2290, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_96MHZ) omap_writew(0x1005, ARM_CKCTL); - omap_writew(0x2410, DPLL_CTL_REG); + omap_writew(0x2410, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_120MHZ) omap_writew(0x110a, ARM_CKCTL); - omap_writew(0x2510, DPLL_CTL_REG); + omap_writew(0x2510, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_168MHZ) omap_writew(0x110f, ARM_CKCTL); - omap_writew(0x2710, DPLL_CTL_REG); + omap_writew(0x2710, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730) omap_writew(0x250E, ARM_CKCTL); - omap_writew(0x2710, DPLL_CTL_REG); + omap_writew(0x2710, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)) omap_writew(0x150f, ARM_CKCTL); if (crystal_type == 2) { source_clock = 13; /* MHz */ - omap_writew(0x2510, DPLL_CTL_REG); + omap_writew(0x2510, DPLL_CTL); } else - omap_writew(0x2810, DPLL_CTL_REG); + omap_writew(0x2810, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730) omap_writew(0x250E, ARM_CKCTL); - omap_writew(0x2790, DPLL_CTL_REG); + omap_writew(0x2790, DPLL_CTL); #else #error "OMAP MHZ not set, please run make xconfig" #endif #ifdef CONFIG_MACH_OMAP_PERSEUS2 /* Select slicer output as OMAP input clock */ - omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL_REG) & ~0x1, OMAP730_PCC_UPLD_CTRL_REG); + omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif /* Turn off some other junk the bootloader might have turned on */ diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/common.c linux-2.6.7/arch/arm/mach-omap/common.c --- linux-2.6.7-rc3/arch/arm/mach-omap/common.c 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-omap/common.c 2004-06-15 23:10:23.587856946 -0700 @@ -25,6 +25,58 @@ /* * ---------------------------------------------------------------------------- + * OMAP revision check + * + * Since we use the cpu_is_omapnnnn() macros, there's a chance that a board + * switches to an updated core. We want to print out the OMAP revision early. + * + * We use the system_serial registers for the revision information so we + * can see it in /proc/cpuinfo. + * + * If the OMAP detection gets more complicated, we may want to expand this + * to store the OMAP version and replace the current cpu_is_omapnnnn() macros. + * + * ---------------------------------------------------------------------------- + */ +static void __init omap_check_revision(void) +{ + system_serial_high = omap_readl(OMAP_ID_BASE); + system_serial_low = OMAP_ID_REG; + system_rev = (OMAP_ID_REG >> ID_SHIFT) & ID_MASK; + + printk("OMAP revision: %d.%d (0x%08x) id: 0x%08x detected as OMAP-", + (system_serial_high >> 20) & 0xf, + (system_serial_high >> 16) & 0xf, + system_serial_high, system_serial_low); + + switch (system_rev) { + case OMAP_ID_730: + printk("730\n"); + system_rev = 0x730; + break; + case OMAP_ID_1510: + printk("1510\n"); + system_rev = 0x1510; + break; + case OMAP_ID_1610: + printk("1610\n"); + system_rev = 0x1610; + break; + case OMAP_ID_1710: + printk("1710\n"); + system_rev = 0x1710; + break; + case OMAP_ID_5912: + printk("5912/1611B\n"); + system_rev = 0x5912; + break; + default: + printk("unknown, please add support!\n"); + } +} + +/* + * ---------------------------------------------------------------------------- * OMAP I/O mapping * * The machine specific code may provide the extra mapping besides the @@ -64,7 +116,13 @@ static struct map_desc omap5912_io_desc[] __initdata = { { OMAP5912_DSP_BASE, OMAP5912_DSP_START, OMAP5912_DSP_SIZE, MT_DEVICE }, { OMAP5912_DSPREG_BASE, OMAP5912_DSPREG_START, OMAP5912_DSPREG_SIZE, MT_DEVICE }, - { OMAP5912_SRAM_BASE, OMAP5912_SRAM_START, OMAP5912_SRAM_SIZE, MT_DEVICE } +/* + * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page + * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped. + * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte + * can be used. + */ + { OMAP5912_SRAM_BASE, OMAP5912_SRAM_START, OMAP5912_SRAM_SIZE + 0x800, MT_DEVICE } }; #endif @@ -77,6 +135,7 @@ /* We have to initialize the IO space mapping before we can run * cpu_is_omapxxx() macros. */ iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); + omap_check_revision(); #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { @@ -102,8 +161,8 @@ /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". */ - omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL_REG); - omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL_REG); + omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); + omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL); /* Must init clocks early to assure that timer interrupt works */ diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/dma.c linux-2.6.7/arch/arm/mach-omap/dma.c --- linux-2.6.7-rc3/arch/arm/mach-omap/dma.c 2004-06-15 23:09:59.997863937 -0700 +++ linux-2.6.7/arch/arm/mach-omap/dma.c 2004-06-15 23:10:23.588856988 -0700 @@ -92,45 +92,124 @@ { u16 w; - w = omap_readw(OMAP_DMA_CSDP_REG(lch)); + w = omap_readw(OMAP_DMA_CSDP(lch)); w &= ~0x03; w |= data_type; - omap_writew(w, OMAP_DMA_CSDP_REG(lch)); + omap_writew(w, OMAP_DMA_CSDP(lch)); - w = omap_readw(OMAP_DMA_CCR_REG(lch)); + w = omap_readw(OMAP_DMA_CCR(lch)); w &= ~(1 << 5); if (sync_mode == OMAP_DMA_SYNC_FRAME) w |= 1 << 5; - omap_writew(w, OMAP_DMA_CCR_REG(lch)); + omap_writew(w, OMAP_DMA_CCR(lch)); - w = omap_readw(OMAP_DMA_CCR2_REG(lch)); + w = omap_readw(OMAP_DMA_CCR2(lch)); w &= ~(1 << 2); if (sync_mode == OMAP_DMA_SYNC_BLOCK) w |= 1 << 2; - omap_writew(w, OMAP_DMA_CCR2_REG(lch)); + omap_writew(w, OMAP_DMA_CCR2(lch)); - omap_writew(elem_count, OMAP_DMA_CEN_REG(lch)); - omap_writew(frame_count, OMAP_DMA_CFN_REG(lch)); + omap_writew(elem_count, OMAP_DMA_CEN(lch)); + omap_writew(frame_count, OMAP_DMA_CFN(lch)); } +void omap_set_dma_constant_fill(int lch, u32 color) +{ + u16 w; + +#ifdef CONFIG_DEBUG_KERNEL + if (omap_dma_in_1510_mode) { + printk(KERN_ERR "OMAP DMA constant fill not available in 1510 mode."); + BUG(); + return; + } +#endif + w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03; + w |= 0x01; + omap_writew(w, OMAP_DMA_CCR2(lch)); + + omap_writew((u16)color, OMAP_DMA_COLOR_L(lch)); + omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch)); + + w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; + w |= 1; /* Channel type G */ + omap_writew(w, OMAP_DMA_LCH_CTRL(lch)); +} + +void omap_set_dma_transparent_copy(int lch, u32 color) +{ + u16 w; + +#ifdef CONFIG_DEBUG_KERNEL + if (omap_dma_in_1510_mode) { + printk(KERN_ERR "OMAP DMA transparent copy not available in 1510 mode."); + BUG(); + } +#endif + w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03; + w |= 0x02; + omap_writew(w, OMAP_DMA_CCR2(lch)); + + omap_writew((u16)color, OMAP_DMA_COLOR_L(lch)); + omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch)); + + w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f; + w |= 1; /* Channel type G */ + omap_writew(w, OMAP_DMA_LCH_CTRL(lch)); +} void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start) { u16 w; - w = omap_readw(OMAP_DMA_CSDP_REG(lch)); + w = omap_readw(OMAP_DMA_CSDP(lch)); w &= ~(0x1f << 2); w |= src_port << 2; - omap_writew(w, OMAP_DMA_CSDP_REG(lch)); + omap_writew(w, OMAP_DMA_CSDP(lch)); - w = omap_readw(OMAP_DMA_CCR_REG(lch)); + w = omap_readw(OMAP_DMA_CCR(lch)); w &= ~(0x03 << 12); w |= src_amode << 12; - omap_writew(w, OMAP_DMA_CCR_REG(lch)); + omap_writew(w, OMAP_DMA_CCR(lch)); + + omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch)); + omap_writew(src_start, OMAP_DMA_CSSA_L(lch)); +} + +void omap_set_dma_src_index(int lch, int eidx, int fidx) +{ + omap_writew(eidx, OMAP_DMA_CSEI(lch)); + omap_writew(fidx, OMAP_DMA_CSFI(lch)); +} + +void omap_set_dma_src_data_pack(int lch, int enable) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6); + w |= enable ? (1 << 6) : 0; + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +void omap_set_dma_src_burst_mode(int lch, int burst_mode) +{ + u16 w; - omap_writew(src_start >> 16, OMAP_DMA_CSSA_U_REG(lch)); - omap_writew(src_start, OMAP_DMA_CSSA_L_REG(lch)); + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7); + switch (burst_mode) { + case OMAP_DMA_DATA_BURST_4: + w |= (0x01 << 7); + break; + case OMAP_DMA_DATA_BURST_8: + w |= (0x03 << 7); + break; + default: + printk(KERN_ERR "Invalid DMA burst mode\n"); + BUG(); + return; + } + omap_writew(w, OMAP_DMA_CSDP(lch)); } void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, @@ -138,18 +217,53 @@ { u16 w; - w = omap_readw(OMAP_DMA_CSDP_REG(lch)); + w = omap_readw(OMAP_DMA_CSDP(lch)); w &= ~(0x1f << 9); w |= dest_port << 9; - omap_writew(w, OMAP_DMA_CSDP_REG(lch)); + omap_writew(w, OMAP_DMA_CSDP(lch)); - w = omap_readw(OMAP_DMA_CCR_REG(lch)); + w = omap_readw(OMAP_DMA_CCR(lch)); w &= ~(0x03 << 14); w |= dest_amode << 14; - omap_writew(w, OMAP_DMA_CCR_REG(lch)); + omap_writew(w, OMAP_DMA_CCR(lch)); - omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U_REG(lch)); - omap_writew(dest_start, OMAP_DMA_CDSA_L_REG(lch)); + omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch)); + omap_writew(dest_start, OMAP_DMA_CDSA_L(lch)); +} + +void omap_set_dma_dest_index(int lch, int eidx, int fidx) +{ + omap_writew(eidx, OMAP_DMA_CDEI(lch)); + omap_writew(fidx, OMAP_DMA_CDFI(lch)); +} + +void omap_set_dma_dest_data_pack(int lch, int enable) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13); + w |= enable ? (1 << 13) : 0; + omap_writew(w, OMAP_DMA_CSDP(lch)); +} + +void omap_set_dma_dest_burst_mode(int lch, int burst_mode) +{ + u16 w; + + w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14); + switch (burst_mode) { + case OMAP_DMA_DATA_BURST_4: + w |= (0x01 << 14); + break; + case OMAP_DMA_DATA_BURST_8: + w |= (0x03 << 14); + break; + default: + printk(KERN_ERR "Invalid DMA burst mode\n"); + BUG(); + return; + } + omap_writew(w, OMAP_DMA_CSDP(lch)); } void omap_start_dma(int lch) @@ -164,38 +278,38 @@ /* Enable the queue, if needed so. */ if (next_lch != -1) { /* Clear the STOP_LNK bits */ - w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch)); + w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); w &= ~(1 << 14); - omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch)); - w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch)); + omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); + w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch)); w &= ~(1 << 14); - omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch)); + omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch)); /* And set the ENABLE_LNK bits */ omap_writew(next_lch | (1 << 15), - OMAP_DMA_CLNK_CTRL_REG(lch)); + OMAP_DMA_CLNK_CTRL(lch)); /* The loop case */ if (dma_chan[next_lch].next_lch == lch) omap_writew(lch | (1 << 15), - OMAP_DMA_CLNK_CTRL_REG(next_lch)); + OMAP_DMA_CLNK_CTRL(next_lch)); /* Read CSR to make sure it's cleared. */ - w = omap_readw(OMAP_DMA_CSR_REG(next_lch)); + w = omap_readw(OMAP_DMA_CSR(next_lch)); /* Enable some nice interrupts. */ omap_writew(dma_chan[next_lch].enabled_irqs, - OMAP_DMA_CICR_REG(next_lch)); + OMAP_DMA_CICR(next_lch)); dma_chan[next_lch].flags |= OMAP_DMA_ACTIVE; } } /* Read CSR to make sure it's cleared. */ - w = omap_readw(OMAP_DMA_CSR_REG(lch)); + w = omap_readw(OMAP_DMA_CSR(lch)); /* Enable some nice interrupts. */ - omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR_REG(lch)); + omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch)); - w = omap_readw(OMAP_DMA_CCR_REG(lch)); + w = omap_readw(OMAP_DMA_CCR(lch)); w |= OMAP_DMA_CCR_EN; - omap_writew(w, OMAP_DMA_CCR_REG(lch)); + omap_writew(w, OMAP_DMA_CCR(lch)); dma_chan[lch].flags |= OMAP_DMA_ACTIVE; } @@ -205,12 +319,12 @@ int next_lch; /* Disable all interrupts on the channel */ - omap_writew(0, OMAP_DMA_CICR_REG(lch)); + omap_writew(0, OMAP_DMA_CICR(lch)); if (omap_dma_in_1510_mode()) { - w = omap_readw(OMAP_DMA_CCR_REG(lch)); + w = omap_readw(OMAP_DMA_CCR(lch)); w &= ~OMAP_DMA_CCR_EN; - omap_writew(w, OMAP_DMA_CCR_REG(lch)); + omap_writew(w, OMAP_DMA_CCR(lch)); dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; return; } @@ -221,16 +335,16 @@ * According to thw HW spec, enabling the STOP_LNK bit * resets the CCR_EN bit at the same time. */ - w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(lch)); + w = omap_readw(OMAP_DMA_CLNK_CTRL(lch)); w |= (1 << 14); - w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(lch)); + w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch)); dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; if (next_lch != -1) { - omap_writew(0, OMAP_DMA_CICR_REG(next_lch)); - w = omap_readw(OMAP_DMA_CLNK_CTRL_REG(next_lch)); + omap_writew(0, OMAP_DMA_CICR(next_lch)); + w = omap_readw(OMAP_DMA_CLNK_CTRL(next_lch)); w |= (1 << 14); - w = omap_writew(w, OMAP_DMA_CLNK_CTRL_REG(next_lch)); + w = omap_writew(w, OMAP_DMA_CLNK_CTRL(next_lch)); dma_chan[next_lch].flags &= ~OMAP_DMA_ACTIVE; } } @@ -253,7 +367,7 @@ csr = dma_chan[ch].saved_csr; dma_chan[ch].saved_csr = 0; } else - csr = omap_readw(OMAP_DMA_CSR_REG(ch)); + csr = omap_readw(OMAP_DMA_CSR(ch)); if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) { dma_chan[ch + 6].saved_csr = csr >> 7; csr &= 0x7f; @@ -339,9 +453,9 @@ } /* Disable the 1510 compatibility mode and set the sync device * id. */ - omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR_REG(free_ch)); + omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch)); } else { - omap_writew(dev_id, OMAP_DMA_CCR_REG(free_ch)); + omap_writew(dev_id, OMAP_DMA_CCR(free_ch)); } *dma_ch_out = free_ch; @@ -362,9 +476,9 @@ spin_unlock_irqrestore(&dma_chan_lock, flags); /* Disable all DMA interrupts for the channel. */ - omap_writew(0, OMAP_DMA_CICR_REG(ch)); + omap_writew(0, OMAP_DMA_CICR(ch)); /* Make sure the DMA transfer is stopped. */ - omap_writew(0, OMAP_DMA_CCR_REG(ch)); + omap_writew(0, OMAP_DMA_CCR(ch)); } int omap_dma_in_1510_mode(void) @@ -601,19 +715,19 @@ enable_1510_mode = 1; } else if (cpu_is_omap1610() || cpu_is_omap5912()) { printk(KERN_INFO "OMAP DMA hardware version %d\n", - omap_readw(OMAP_DMA_HW_ID_REG)); + omap_readw(OMAP_DMA_HW_ID)); printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", - (omap_readw(OMAP_DMA_CAPS_0_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_0_L_REG), - (omap_readw(OMAP_DMA_CAPS_1_U_REG) << 16) | omap_readw(OMAP_DMA_CAPS_1_L_REG), - omap_readw(OMAP_DMA_CAPS_2_REG), omap_readw(OMAP_DMA_CAPS_3_REG), - omap_readw(OMAP_DMA_CAPS_4_REG)); + (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L), + (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L), + omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3), + omap_readw(OMAP_DMA_CAPS_4)); if (!enable_1510_mode) { u16 w; /* Disable OMAP 3.0/3.1 compatibility mode. */ - w = omap_readw(OMAP_DMA_GSCR_REG); + w = omap_readw(OMAP_DMA_GSCR); w |= 1 << 3; - omap_writew(w, OMAP_DMA_GSCR_REG); + omap_writew(w, OMAP_DMA_GSCR); dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT; } else dma_chan_count = 9; @@ -657,9 +771,21 @@ EXPORT_SYMBOL(omap_free_dma); EXPORT_SYMBOL(omap_start_dma); EXPORT_SYMBOL(omap_stop_dma); + EXPORT_SYMBOL(omap_set_dma_transfer_params); +EXPORT_SYMBOL(omap_set_dma_constant_fill); +EXPORT_SYMBOL(omap_set_dma_transparent_copy); + EXPORT_SYMBOL(omap_set_dma_src_params); +EXPORT_SYMBOL(omap_set_dma_src_index); +EXPORT_SYMBOL(omap_set_dma_src_data_pack); +EXPORT_SYMBOL(omap_set_dma_src_burst_mode); + EXPORT_SYMBOL(omap_set_dma_dest_params); +EXPORT_SYMBOL(omap_set_dma_dest_index); +EXPORT_SYMBOL(omap_set_dma_dest_data_pack); +EXPORT_SYMBOL(omap_set_dma_dest_burst_mode); + EXPORT_SYMBOL(omap_dma_link_lch); EXPORT_SYMBOL(omap_dma_unlink_lch); diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/fpga.c linux-2.6.7/arch/arm/mach-omap/fpga.c --- linux-2.6.7-rc3/arch/arm/mach-omap/fpga.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-omap/fpga.c 2004-06-15 23:10:23.589857030 -0700 @@ -46,11 +46,11 @@ irq -= IH_FPGA_BASE; if (irq < 8) - __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO) - & ~(1 << irq)), OMAP1510P1_FPGA_IMR_LO); + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) + & ~(1 << irq)), OMAP1510_FPGA_IMR_LO); else if (irq < 16) - __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI) - & ~(1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI); + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI) + & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI); else __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2) & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2); @@ -60,10 +60,10 @@ static inline u32 get_fpga_unmasked_irqs(void) { return - ((__raw_readb(OMAP1510P1_FPGA_ISR_LO) & - __raw_readb(OMAP1510P1_FPGA_IMR_LO))) | - ((__raw_readb(OMAP1510P1_FPGA_ISR_HI) & - __raw_readb(OMAP1510P1_FPGA_IMR_HI)) << 8) | + ((__raw_readb(OMAP1510_FPGA_ISR_LO) & + __raw_readb(OMAP1510_FPGA_IMR_LO))) | + ((__raw_readb(OMAP1510_FPGA_ISR_HI) & + __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) | ((__raw_readb(INNOVATOR_FPGA_ISR2) & __raw_readb(INNOVATOR_FPGA_IMR2)) << 16); } @@ -79,11 +79,11 @@ irq -= IH_FPGA_BASE; if (irq < 8) - __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_LO) | (1 << irq)), - OMAP1510P1_FPGA_IMR_LO); + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)), + OMAP1510_FPGA_IMR_LO); else if (irq < 16) - __raw_writeb((__raw_readb(OMAP1510P1_FPGA_IMR_HI) - | (1 << (irq - 8))), OMAP1510P1_FPGA_IMR_HI); + __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI) + | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI); else __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2) | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2); @@ -166,8 +166,8 @@ { int i; - __raw_writeb(0, OMAP1510P1_FPGA_IMR_LO); - __raw_writeb(0, OMAP1510P1_FPGA_IMR_HI); + __raw_writeb(0, OMAP1510_FPGA_IMR_LO); + __raw_writeb(0, OMAP1510_FPGA_IMR_HI); __raw_writeb(0, INNOVATOR_FPGA_IMR2); for (i = IH_FPGA_BASE; i < (IH_FPGA_BASE + NR_FPGA_IRQS); i++) { diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/gpio.c linux-2.6.7/arch/arm/mach-omap/gpio.c --- linux-2.6.7-rc3/arch/arm/mach-omap/gpio.c 2004-06-15 23:09:59.998863979 -0700 +++ linux-2.6.7/arch/arm/mach-omap/gpio.c 2004-06-15 23:10:23.590857072 -0700 @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -79,7 +78,7 @@ #define OMAP730_GPIO_INT_MASK 0x10 #define OMAP730_GPIO_INT_STATUS 0x14 -#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) +#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) struct gpio_bank { u32 base; @@ -213,12 +212,12 @@ reg += OMAP730_GPIO_DIR_CONTROL; break; } - l = omap_readl(reg); + l = __raw_readl(reg); if (is_input) l |= 1 << gpio; else l &= ~(1 << gpio); - omap_writel(l, reg); + __raw_writel(l, reg); } void omap_set_gpio_direction(int gpio, int is_input) @@ -240,8 +239,8 @@ switch (bank->method) { case METHOD_MPUIO: - reg += OMAP_MPUIO_OUTPUT_REG; - l = omap_readl(reg); + reg += OMAP_MPUIO_OUTPUT; + l = __raw_readl(reg); if (enable) l |= 1 << gpio; else @@ -249,7 +248,7 @@ break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DATA_OUTPUT; - l = omap_readl(reg); + l = __raw_readl(reg); if (enable) l |= 1 << gpio; else @@ -264,7 +263,7 @@ break; case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_OUTPUT; - l = omap_readl(reg); + l = __raw_readl(reg); if (enable) l |= 1 << gpio; else @@ -274,7 +273,7 @@ BUG(); return; } - omap_writel(l, reg); + __raw_writel(l, reg); } void omap_set_gpio_dataout(int gpio, int enable) @@ -312,7 +311,7 @@ BUG(); return -1; } - return (omap_readl(reg) & (1 << get_gpio_index(gpio))) != 0; + return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; } static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) @@ -322,22 +321,22 @@ switch (bank->method) { case METHOD_MPUIO: - reg += OMAP_MPUIO_GPIO_INT_EDGE_REG; - l = omap_readl(reg); + reg += OMAP_MPUIO_GPIO_INT_EDGE; + l = __raw_readl(reg); if (edge == OMAP_GPIO_RISING_EDGE) l |= 1 << gpio; else l &= ~(1 << gpio); - omap_writel(l, reg); + __raw_writel(l, reg); break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; - l = omap_readl(reg); + l = __raw_readl(reg); if (edge == OMAP_GPIO_RISING_EDGE) l |= 1 << gpio; else l &= ~(1 << gpio); - omap_writel(l, reg); + __raw_writel(l, reg); break; case METHOD_GPIO_1610: edge &= 0x03; @@ -346,19 +345,19 @@ else reg += OMAP1610_GPIO_EDGE_CTRL1; gpio &= 0x07; - l = omap_readl(reg); + l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); l |= edge << (gpio << 1); - omap_writel(l, reg); + __raw_writel(l, reg); break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; - l = omap_readl(reg); + l = __raw_readl(reg); if (edge == OMAP_GPIO_RISING_EDGE) l |= 1 << gpio; else l &= ~(1 << gpio); - omap_writel(l, reg); + __raw_writel(l, reg); break; default: BUG(); @@ -385,11 +384,11 @@ switch (bank->method) { case METHOD_MPUIO: - l = omap_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE_REG); + l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE); return (l & (1 << gpio)) ? OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; case METHOD_GPIO_1510: - l = omap_readl(reg + OMAP1510_GPIO_INT_CONTROL); + l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL); return (l & (1 << gpio)) ? OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; case METHOD_GPIO_1610: @@ -397,9 +396,9 @@ reg += OMAP1610_GPIO_EDGE_CTRL2; else reg += OMAP1610_GPIO_EDGE_CTRL1; - return (omap_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03; + return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03; case METHOD_GPIO_730: - l = omap_readl(reg + OMAP730_GPIO_INT_CONTROL); + l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL); return (l & (1 << gpio)) ? OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; default: @@ -430,7 +429,7 @@ BUG(); return; } - omap_writel(1 << get_gpio_index(gpio), reg); + __raw_writel(1 << get_gpio_index(gpio), reg); } static void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable) @@ -441,7 +440,7 @@ switch (bank->method) { case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; - l = omap_readl(reg); + l = __raw_readl(reg); if (enable) l &= ~(1 << gpio); else @@ -449,7 +448,7 @@ break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; - l = omap_readl(reg); + l = __raw_readl(reg); if (enable) l &= ~(1 << gpio); else @@ -465,7 +464,7 @@ break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; - l = omap_readl(reg); + l = __raw_readl(reg); if (enable) l &= ~(1 << gpio); else @@ -475,7 +474,7 @@ BUG(); return; } - omap_writel(l, reg); + __raw_writel(l, reg); } int omap_request_gpio(int gpio) @@ -500,7 +499,7 @@ /* Claim the pin for the ARM */ reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; - omap_writel(omap_readl(reg) | (1 << get_gpio_index(gpio)), reg); + __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } #endif spin_unlock(&bank->lock); @@ -564,7 +563,7 @@ isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; #endif for (;;) { - u32 isr = omap_readl(isr_reg); + u32 isr = __raw_readl(isr_reg); unsigned int gpio_irq; if (!isr) @@ -587,15 +586,15 @@ #ifdef CONFIG_ARCH_OMAP1510 if (bank->method == METHOD_GPIO_1510) - omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS); + __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1510_GPIO_INT_STATUS); #endif #if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) if (bank->method == METHOD_GPIO_1610) - omap_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1); + __raw_writew(1 << (gpio & 0x0f), bank->base + OMAP1610_GPIO_IRQSTATUS1); #endif #ifdef CONFIG_ARCH_OMAP730 if (bank->method == METHOD_GPIO_730) - omap_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS); + __raw_writel(1 << (gpio & 0x1f), bank->base + OMAP730_GPIO_INT_STATUS); #endif } @@ -692,26 +691,27 @@ bank = &gpio_bank[i]; bank->reserved_map = 0; + bank->base = IO_ADDRESS(bank->base); spin_lock_init(&bank->lock); if (bank->method == METHOD_MPUIO) { omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); } #ifdef CONFIG_ARCH_OMAP1510 if (bank->method == METHOD_GPIO_1510) { - omap_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); - omap_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); + __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); + __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS); } #endif #if defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) if (bank->method == METHOD_GPIO_1610) { - omap_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); - omap_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); + __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); + __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); } #endif #ifdef CONFIG_ARCH_OMAP730 if (bank->method == METHOD_GPIO_730) { - omap_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK); - omap_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS); + __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK); + __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS); gpio_count = 32; /* 730 has 32-bit GPIOs */ } @@ -730,9 +730,9 @@ } /* Enable system clock for GPIO module. - * The CAM_CLK_CTRL_REG *is* really the right place. */ + * The CAM_CLK_CTRL *is* really the right place. */ if (cpu_is_omap1610()) - omap_writel(omap_readl(ULPD_CAM_CLK_CTRL_REG) | 0x04, ULPD_CAM_CLK_CTRL_REG); + omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); return 0; } @@ -748,8 +748,11 @@ return 0; } -EXPORT_SYMBOL(omap_gpio_init); EXPORT_SYMBOL(omap_request_gpio); EXPORT_SYMBOL(omap_free_gpio); +EXPORT_SYMBOL(omap_set_gpio_direction); +EXPORT_SYMBOL(omap_set_gpio_dataout); +EXPORT_SYMBOL(omap_get_gpio_datain); +EXPORT_SYMBOL(omap_set_gpio_edge_ctrl); arch_initcall(omap_gpio_init); diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/irq.c linux-2.6.7/arch/arm/mach-omap/irq.c --- linux-2.6.7-rc3/arch/arm/mach-omap/irq.c 2004-06-15 23:10:00.002864147 -0700 +++ linux-2.6.7/arch/arm/mach-omap/irq.c 2004-06-15 23:10:23.593857198 -0700 @@ -74,9 +74,9 @@ static void omap_ack_irq(unsigned int irq) { if (irq > 31) - omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG); + omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET); - omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG); + omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET); } static void omap_mask_irq(unsigned int irq) @@ -84,9 +84,9 @@ int bank = IRQ_BANK(irq); u32 l; - l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR); + l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); l |= 1 << IRQ_BIT(irq); - omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR); + omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); } static void omap_unmask_irq(unsigned int irq) @@ -94,9 +94,9 @@ int bank = IRQ_BANK(irq); u32 l; - l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR); + l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); l &= ~(1 << IRQ_BIT(irq)); - omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR); + omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET); } static void omap_mask_ack_irq(unsigned int irq) @@ -121,7 +121,7 @@ /* FIQ is only available on bank 0 interrupts */ fiq = bank ? 0 : (fiq & 0x1); val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1); - offset = IRQ_ILR0 + IRQ_BIT(irq) * 0x4; + offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4; irq_bank_writel(val, bank, offset); } @@ -182,13 +182,13 @@ /* Mask and clear all interrupts */ for (i = 0; i < irq_bank_count; i++) { - irq_bank_writel(~0x0, i, IRQ_MIR); - irq_bank_writel(0x0, i, IRQ_ITR); + irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET); + irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET); } /* Clear any pending interrupts */ - irq_bank_writel(0x03, 0, IRQ_CONTROL_REG); - irq_bank_writel(0x03, 1, IRQ_CONTROL_REG); + irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET); + irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET); /* Install the interrupt handlers for each bank */ for (i = 0; i < irq_bank_count; i++) { diff -urN linux-2.6.7-rc3/arch/arm/mach-omap/ocpi.c linux-2.6.7/arch/arm/mach-omap/ocpi.c --- linux-2.6.7-rc3/arch/arm/mach-omap/ocpi.c 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-omap/ocpi.c 2004-06-15 23:10:23.596857325 -0700 @@ -85,14 +85,6 @@ val &= ~0xff; omap_writel(val, OCPI_SEC); - val = omap_readl(OCPI_SEC); - val |= 0; - omap_writel(val, OCPI_SEC); - - val = omap_readl(OCPI_SINT0); - val |= 0; - omap_writel(val, OCPI_SINT1); - return 0; } EXPORT_SYMBOL(ocpi_enable); diff -urN linux-2.6.7-rc3/arch/arm/mach-pxa/Kconfig linux-2.6.7/arch/arm/mach-pxa/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-pxa/Kconfig 2004-06-15 23:10:00.007864358 -0700 +++ linux-2.6.7/arch/arm/mach-pxa/Kconfig 2004-06-15 23:10:23.599857451 -0700 @@ -1,9 +1,9 @@ +if ARCH_PXA menu "Intel PXA2xx Implementations" choice prompt "Select target board" - depends on ARCH_PXA config ARCH_LUBBOCK bool "Intel DBPXA250 Development Platform" @@ -32,3 +32,4 @@ help Select code specific to PXA27x variants +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-s3c2410/Kconfig linux-2.6.7/arch/arm/mach-s3c2410/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-s3c2410/Kconfig 2004-06-15 23:10:00.012864568 -0700 +++ linux-2.6.7/arch/arm/mach-s3c2410/Kconfig 2004-06-15 23:10:23.604857662 -0700 @@ -1,8 +1,9 @@ +if ARCH_S3C2410 + menu "S3C2410 Implementations" config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" - depends on ARCH_S3C2410 help Say Y here if you are using the Simtec Electronics EB2410ITX development board (also known as BAST) @@ -11,22 +12,21 @@ config ARCH_H1940 bool "IPAQ H1940" - depends on ARCH_S3C2410 help Say Y here if you are using the HP IPAQ H1940 . config ARCH_SMDK2410 bool "SMDK2410/A9M2410" - depends on ARCH_S3C2410 help Say Y here if you are using the SMDK2410 or the derived module A9M2410 config MACH_VR1000 bool "Simtec VR1000" - depends on ARCH_S3C2410 help Say Y here if you are using the Simtec VR1000 board. endmenu + +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-sa1100/Kconfig linux-2.6.7/arch/arm/mach-sa1100/Kconfig --- linux-2.6.7-rc3/arch/arm/mach-sa1100/Kconfig 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/arch/arm/mach-sa1100/Kconfig 2004-06-15 23:10:23.606857746 -0700 @@ -1,9 +1,9 @@ +if ARCH_SA1100 menu "SA11x0 Implementations" config SA1100_ASSABET bool "Assabet" - depends on ARCH_SA1100 help Say Y here if you are using the Intel(R) StrongARM(R) SA-1110 Microprocessor Development Board (also known as the Assabet). @@ -18,7 +18,6 @@ config SA1100_ADSBITSY bool "ADS Bitsy" - depends on ARCH_SA1100 help Say Y here if you are using Applied Data Systems Intel(R) StrongARM(R) 1110 based Bitsy, 3 x 5 inches in size, Compaq - IPAQ - @@ -28,14 +27,12 @@ config SA1100_BRUTUS bool "Brutus" - depends on ARCH_SA1100 help Say Y here if you are using the Intel(R) StrongARM(R) SA-1100 Microprocessor Development Board (also known as the Brutus). config SA1100_CERF bool "CerfBoard" - depends on ARCH_SA1100 help The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued). More information is available at: @@ -62,7 +59,6 @@ config SA1100_H3100 bool "Compaq iPAQ H3100" - depends on ARCH_SA1100 help Say Y here if you intend to run this kernel on the Compaq iPAQ H3100 handheld computer. Information about this machine and the @@ -73,7 +69,6 @@ config SA1100_H3600 bool "Compaq iPAQ H3600/H3700" - depends on ARCH_SA1100 help Say Y here if you intend to run this kernel on the Compaq iPAQ H3600 handheld computer. Information about this machine and the @@ -84,7 +79,6 @@ config SA1100_H3800 bool "Compaq iPAQ H3800" - depends on ARCH_SA1100 help Say Y here if you intend to run this kernel on the Compaq iPAQ H3800 series handheld computer. Information about this machine and the @@ -102,7 +96,6 @@ #dep_bool ' Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100 config SA1100_EXTENEX1 bool "Extenex HandHeld Theater (Squashtail)" - depends on ARCH_SA1100 config SA1100_EXTENEX1_16MB bool "Support 16 MB of DRAM (not just 8)" @@ -110,7 +103,6 @@ config SA1100_FLEXANET bool "FlexaNet" - depends on ARCH_SA1100 help Say Y here if you intend to run this kernel on the FlexaNet handheld instruments. Information about this machine can be @@ -118,14 +110,12 @@ config SA1100_FREEBIRD bool "FreeBird-v1.1" - depends on ARCH_SA1100 help Support the FreeBird board used in Coventive embedded products. See Documentation/arm/SA1100/Freebird for more. config SA1100_GRAPHICSCLIENT bool "GraphicsClient Plus" - depends on ARCH_SA1100 help Say Y here if you are using an Applied Data Systems Intel(R) StrongARM(R) SA-1100 based Graphics Client SBC. See @@ -133,7 +123,6 @@ config SA1100_GRAPHICSMASTER bool "GraphicsMaster" - depends on ARCH_SA1100 help Say Y here if you are using an Applied Data Systems Intel(R) StrongARM(R) SA-1100 based Graphics Master SBC with SA-1111 @@ -143,14 +132,12 @@ config SA1100_BADGE4 bool "HP Labs BadgePAD 4" - depends on ARCH_SA1100 help Say Y here if you want to build a kernel for the HP Laboratories BadgePAD 4. config SA1100_JORNADA720 bool "HP Jornada 720" - depends on ARCH_SA1100 help Say Y here if you want to build a kernel for the HP Jornada 720 handheld computer. See @@ -158,14 +145,12 @@ config SA1100_HACKKIT bool "HackKit Core CPU Board" - depends on ARCH_SA1100 help Say Y here to support the HackKit Core CPU Board ; config SA1100_HUW_WEBPANEL bool "HuW WebPanel" - depends on ARCH_SA1100 help Say Y here to support the HuW Webpanel produced by Hoeft & Wessel AG. English-language website is at @@ -174,7 +159,6 @@ config SA1100_ITSY bool "Itsy" - depends on ARCH_SA1100 help Say Y here if you are using the Compaq Itsy experimental pocket computer. See for @@ -182,7 +166,6 @@ config SA1100_LART bool "LART" - depends on ARCH_SA1100 help Say Y here if you are using the Linux Advanced Radio Terminal (also known as the LART). See for @@ -190,7 +173,6 @@ config SA1100_NANOENGINE bool "nanoEngine" - depends on ARCH_SA1100 help The nanoEngine is a StrongARM 1110-based single board computer from Bright Star Engineering. More information is available at: @@ -201,14 +183,12 @@ config SA1100_OMNIMETER bool "OmniMeter" - depends on ARCH_SA1100 help Say Y here if you are using the inhand electronics OmniMeter. See for details. config SA1100_PANGOLIN bool "Pangolin" - depends on ARCH_SA1100 help Pangolin is a StrongARM 1110-based evaluation platform produced by Dialogue Technology. It has EISA slots for ease of configuration @@ -220,7 +200,6 @@ config SA1100_PLEB bool "PLEB" - depends on ARCH_SA1100 help Say Y here if you are using a Portable Linux Embedded Board (also known as PLEB). See @@ -228,7 +207,6 @@ config SA1100_PT_SYSTEM3 bool "PT System 3" - depends on ARCH_SA1100 help Say Y here if you intend to build a kernel suitable to run on a Pruftechnik Digital Board. For more information see @@ -236,7 +214,6 @@ config SA1100_SHANNON bool "Shannon" - depends on ARCH_SA1100 help The Shannon (also known as a Tuxscreen, and also as a IS2630) was a limited edition webphone produced by Philips. The Shannon is a SA1100 @@ -245,7 +222,6 @@ config SA1100_SHERMAN bool "Sherman" - depends on ARCH_SA1100 help Say Y here to support the Blazie Engineering `Sherman' StrongARM 1110-based SBC, used primarily in assistance products for the @@ -255,7 +231,6 @@ config SA1100_SIMPAD bool "Simpad" - depends on ARCH_SA1100 help The SIEMENS webpad SIMpad is based on the StrongARM 1110. There are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB @@ -266,7 +241,6 @@ config SA1100_PFS168 bool "Tulsa" - depends on ARCH_SA1100 help The Radisys Corp. PFS-168 (aka Tulsa) is an Intel® StrongArm® SA-1110 based computer which includes the SA-1111 Microprocessor Companion Chip and other @@ -276,7 +250,6 @@ config SA1100_VICTOR bool "Victor" - depends on ARCH_SA1100 help Say Y here if you are using a Visu Aide Intel(R) StrongARM(R) SA-1100 based Victor Digital Talking Book Reader. See @@ -285,14 +258,12 @@ config SA1100_XP860 bool "XP860" - depends on ARCH_SA1100 help :: Config help missing :: :: 06 August 2002 :: config SA1100_YOPY bool "Yopy" - depends on ARCH_SA1100 help Say Y here to support the Yopy PDA. Product information at . See Documentation/arm/SA1100/Yopy @@ -300,14 +271,12 @@ config SA1100_STORK bool "Stork" - depends on ARCH_SA1100 help Say Y here if you intend to run this kernel on the Stork handheld computer. #config SA1100_TRIZEPS # bool "Trizeps" -# depends on ARCH_SA1100 # help # :: write me :: @@ -319,7 +288,6 @@ config SA1100_SSP tristate "Generic PIO SSP" - depends on ARCH_SA1100 help Say Y here to enable support for the generic PIO SSP driver. This isn't for audio support, but for attached sensors and @@ -328,7 +296,6 @@ config SA1100_USB tristate "SA1100 USB function support" - depends on ARCH_SA1100 config SA1100_USB_NETLINK tristate "Support for SA11x0 USB network link function" @@ -349,3 +316,4 @@ endmenu +endif diff -urN linux-2.6.7-rc3/arch/arm/mach-sa1100/cpu-sa1100.c linux-2.6.7/arch/arm/mach-sa1100/cpu-sa1100.c --- linux-2.6.7-rc3/arch/arm/mach-sa1100/cpu-sa1100.c 2004-06-15 23:10:00.014864653 -0700 +++ linux-2.6.7/arch/arm/mach-sa1100/cpu-sa1100.c 2004-06-15 23:10:23.606857746 -0700 @@ -230,8 +230,9 @@ } static struct cpufreq_driver sa1100_driver = { - .flags = (CPUFREQ_PANIC_OUTOFSYNC | - CPUFREQ_PANIC_RESUME_OUTOFSYNC), + .flags = CPUFREQ_STICKY | + CPUFREQ_PANIC_OUTOFSYNC | + CPUFREQ_PANIC_RESUME_OUTOFSYNC, .verify = sa11x0_verify_speed, .target = sa1100_target, .get = sa11x0_getspeed, diff -urN linux-2.6.7-rc3/arch/arm/mach-sa1100/cpu-sa1110.c linux-2.6.7/arch/arm/mach-sa1100/cpu-sa1110.c --- linux-2.6.7-rc3/arch/arm/mach-sa1100/cpu-sa1110.c 2004-06-15 23:10:00.014864653 -0700 +++ linux-2.6.7/arch/arm/mach-sa1100/cpu-sa1110.c 2004-06-15 23:10:23.607857788 -0700 @@ -329,8 +329,9 @@ } static struct cpufreq_driver sa1110_driver = { - .flags = (CPUFREQ_PANIC_OUTOFSYNC | - CPUFREQ_PANIC_RESUME_OUTOFSYNC), + .flags = CPUFREQ_STICKY | + CPUFREQ_PANIC_OUTOFSYNC | + CPUFREQ_PANIC_RESUME_OUTOFSYNC, .verify = sa11x0_verify_speed, .target = sa1110_target, .get = sa11x0_getspeed, diff -urN linux-2.6.7-rc3/arch/i386/Kconfig linux-2.6.7/arch/i386/Kconfig --- linux-2.6.7-rc3/arch/i386/Kconfig 2004-06-15 23:10:00.068866926 -0700 +++ linux-2.6.7/arch/i386/Kconfig 2004-06-15 23:10:23.660860019 -0700 @@ -65,6 +65,8 @@ config X86_NUMAQ bool "NUMAQ (IBM/Sequent)" + select DISCONTIGMEM + select NUMA help This option is used for getting Linux to run on a (IBM/Sequent) NUMA multiquad box. This changes the way that processors are bootstrapped, @@ -548,6 +550,7 @@ config X86_MCE bool "Machine Check Exception" + depends on !X86_VOYAGER ---help--- Machine Check Exception support allows the processor to notify the kernel if it detects a problem (e.g. overheating, component failure). diff -urN linux-2.6.7-rc3/arch/i386/defconfig linux-2.6.7/arch/i386/defconfig --- linux-2.6.7-rc3/arch/i386/defconfig 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/i386/defconfig 2004-06-15 23:10:23.664860188 -0700 @@ -18,8 +18,11 @@ # CONFIG_SWAP=y CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_LOG_BUF_SHIFT=15 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -30,6 +33,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # @@ -88,6 +92,7 @@ # CONFIG_HPET_EMULATE_RTC is not set CONFIG_SMP=y CONFIG_NR_CPUS=8 +CONFIG_SCHED_SMT=y CONFIG_PREEMPT=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y @@ -200,7 +205,7 @@ # # Generic Driver Options # -# CONFIG_FW_LOADER is not set +CONFIG_FW_LOADER=m # # Memory Technology Devices (MTD) @@ -259,7 +264,6 @@ # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -307,6 +311,7 @@ # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set # CONFIG_IDE_CHIPSETS is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -332,7 +337,6 @@ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # # CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_REPORT_LUNS=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -354,6 +358,7 @@ # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +CONFIG_SCSI_DPT_I2O=m # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_MEGARAID is not set @@ -361,7 +366,9 @@ # CONFIG_SCSI_SATA_SVW is not set CONFIG_SCSI_ATA_PIIX=y # CONFIG_SCSI_SATA_PROMISE is not set +CONFIG_SCSI_SATA_SX4=m # CONFIG_SCSI_SATA_SIL is not set +CONFIG_SCSI_SATA_SIS=m # CONFIG_SCSI_SATA_VIA is not set # CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_BUSLOGIC is not set @@ -380,6 +387,9 @@ # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_TRACE is not set +# CONFIG_SCSI_IPR_DUMP is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set @@ -484,8 +494,6 @@ # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -539,13 +547,17 @@ CONFIG_IP_NF_ARPTABLES=y CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_RAW=m # # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set +# CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -566,12 +578,12 @@ # Network testing # # CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -579,6 +591,11 @@ # CONFIG_NET_SB1000 is not set # +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y @@ -619,7 +636,6 @@ # CONFIG_8139TOO_TUNE_TWISTER is not set # CONFIG_8139TOO_8129 is not set # CONFIG_8139_OLD_RX_RESET is not set -CONFIG_8139_RXBUF_IDX=2 # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -637,7 +653,6 @@ # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set -# CONFIG_SIS190 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set @@ -645,47 +660,31 @@ # Ethernet (10000 Mbit) # # CONFIG_IXGB is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set +CONFIG_S2IO=m +# CONFIG_S2IO_NAPI is not set # # Token Ring devices # # CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set # -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support +# Wireless LAN (non-hamradio) # -# CONFIG_IRDA is not set +# CONFIG_NET_RADIO is not set # -# Bluetooth support +# Wan interfaces # -# CONFIG_BT is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # # ISDN subsystem @@ -803,6 +802,7 @@ # CONFIG_AGP_AMD is not set # CONFIG_AGP_AMD64 is not set CONFIG_AGP_INTEL=y +CONFIG_AGP_INTEL_MCH=m # CONFIG_AGP_NVIDIA is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_SWORKS is not set @@ -978,6 +978,7 @@ # CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_OHCI_HCD is not set CONFIG_USB_UHCI_HCD=y @@ -1012,6 +1013,7 @@ # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +CONFIG_USB_EGALAX=m # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1061,6 +1063,8 @@ # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGETSERVO=m # CONFIG_USB_TEST is not set # @@ -1110,6 +1114,7 @@ # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y @@ -1152,7 +1157,6 @@ # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -1217,6 +1221,7 @@ CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_FRAME_POINTER is not set +CONFIG_4KSTACKS=y CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y @@ -1234,8 +1239,10 @@ # Library routines # CONFIG_CRC32=y +CONFIG_LIBCRC32C=m CONFIG_X86_SMP=y CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_STD_RESOURCES=y CONFIG_PC=y diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/elanfreq.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/elanfreq.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/elanfreq.c 2004-06-15 23:10:00.072867094 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/elanfreq.c 2004-06-15 23:10:23.667860314 -0700 @@ -254,6 +254,7 @@ static int __init elanfreq_setup(char *str) { max_freq = simple_strtoul(str, &str, 0); + printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n"); return 1; } __setup("elanfreq=", elanfreq_setup); @@ -300,7 +301,7 @@ } -MODULE_PARM (max_freq, "i"); +module_param (max_freq, int, 0444); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Robert Schwebel , Sven Geggus "); diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c 2004-06-15 23:10:00.073867136 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c 2004-06-15 23:10:23.667860314 -0700 @@ -124,7 +124,7 @@ /* PCI bus clock - defaults to 30.000 if cpu_khz is not available */ static int pci_busclk = 0; -MODULE_PARM(pci_busclk, "i"); +module_param (pci_busclk, int, 0444); /* maximum duration for which the cpu may be suspended * (32us * MAX_DURATION). If no parameter is given, this defaults @@ -133,7 +133,7 @@ * is suspended -- processing power is just 0.39% of what it used to be, * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */ static int max_duration = 255; -MODULE_PARM(max_duration, "i"); +module_param (max_duration, int, 0444); /* For the default policy, we want at least some processing power * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV) diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/longhaul.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/longhaul.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/longhaul.c 2004-06-15 23:10:00.074867178 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/longhaul.c 2004-06-15 23:10:23.668860356 -0700 @@ -36,6 +36,7 @@ static unsigned int numscales=16, numvscales; static unsigned int fsb; static int minvid, maxvid; +static unsigned int minmult, maxmult; static int can_scale_voltage; static int vrmrev; @@ -45,11 +46,15 @@ static void dprintk(const char *fmt, ...) { + char s[256]; va_list args; + if (debug == 0) return; + va_start(args, fmt); - printk(fmt, args); + vsprintf(s, fmt, args); + printk(s); va_end(args); } @@ -65,7 +70,7 @@ static struct cpufreq_frequency_table *longhaul_table; -static unsigned int calc_speed (int mult, int fsb) +static unsigned int calc_speed(int mult, int fsb) { int khz; khz = (mult/10)*fsb; @@ -76,7 +81,7 @@ } -static int longhaul_get_cpu_mult (void) +static int longhaul_get_cpu_mult(void) { unsigned long invalue=0,lo, hi; @@ -97,7 +102,7 @@ * Sets a new clock ratio, and -if applicable- a new Front Side Bus */ -static void longhaul_setstate (unsigned int clock_ratio_index) +static void longhaul_setstate(unsigned int clock_ratio_index) { int speed, mult; struct cpufreq_freqs freqs; @@ -193,7 +198,7 @@ #define ROUNDING 0xf -static int _guess (int guess, int maxmult) +static int _guess(int guess) { int target; @@ -206,7 +211,7 @@ } -static int guess_fsb(int maxmult) +static int guess_fsb(void) { int speed = (cpu_khz/1000); int i; @@ -216,18 +221,17 @@ speed &= ~ROUNDING; for (i=0; i<3; i++) { - if (_guess(speeds[i],maxmult) == speed) + if (_guess(speeds[i]) == speed) return speeds[i]; } return 0; } -static int __init longhaul_get_ranges (void) +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]= { 50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65, -1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 }; @@ -248,7 +252,7 @@ if (c->x86_model==6) fsb = eblcr_fsb_table_v1[invalue]; else - fsb = guess_fsb(maxmult); + fsb = guess_fsb(); break; case 2: @@ -398,7 +402,7 @@ } -static int longhaul_target (struct cpufreq_policy *policy, +static int longhaul_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { @@ -422,7 +426,7 @@ return (calc_speed (longhaul_get_cpu_mult(), fsb)); } -static int __init longhaul_cpu_init (struct cpufreq_policy *policy) +static int __init longhaul_cpu_init(struct cpufreq_policy *policy) { struct cpuinfo_x86 *c = cpu_data; char *cpuname=NULL; @@ -536,7 +540,7 @@ .attr = longhaul_attr, }; -static int __init longhaul_init (void) +static int __init longhaul_init(void) { struct cpuinfo_x86 *c = cpu_data; @@ -553,8 +557,17 @@ return -ENODEV; } -static void __exit longhaul_exit (void) +static void __exit longhaul_exit(void) { + int i=0; + unsigned int new_clock_ratio; + + while (clock_ratio[i] != maxmult) + i++; + + new_clock_ratio = longhaul_table[i].index & 0xFF; + longhaul_setstate(new_clock_ratio); + cpufreq_unregister_driver(&longhaul_driver); kfree(longhaul_table); } diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2004-06-15 23:10:00.076867262 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c 2004-06-15 23:10:23.670860440 -0700 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -132,34 +133,28 @@ #endif /* notifiers */ - for_each_cpu(i) { - if (cpu_isset(i, affected_cpu_map)) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - } + for_each_cpu_mask(i, affected_cpu_map) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); } /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software * Developer's Manual, Volume 3 */ - for_each_cpu(i) { - if (cpu_isset(i, affected_cpu_map)) { - cpumask_t this_cpu = cpumask_of_cpu(i); + for_each_cpu_mask(i, affected_cpu_map) { + cpumask_t this_cpu = cpumask_of_cpu(i); - set_cpus_allowed(current, this_cpu); - BUG_ON(smp_processor_id() != i); + set_cpus_allowed(current, this_cpu); + BUG_ON(smp_processor_id() != i); - cpufreq_p4_setdc(i, p4clockmod_table[newstate].index); - } + cpufreq_p4_setdc(i, p4clockmod_table[newstate].index); } set_cpus_allowed(current, cpus_allowed); /* notifiers */ - for_each_cpu(i) { - if (cpu_isset(i, affected_cpu_map)) { - freqs.cpu = i; - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - } + for_each_cpu_mask(i, affected_cpu_map) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } return 0; diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/powernow-k8.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/powernow-k8.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-06-15 23:10:00.078867346 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/powernow-k8.c 2004-06-15 23:10:23.672860524 -0700 @@ -733,10 +733,22 @@ continue; } - /* verify only 1 entry from the lo frequency table */ - if ((fid < HI_FID_TABLE_BOTTOM) && (cntlofreq++)) { - printk(KERN_ERR PFX "Too many lo freq table entries\n"); - goto err_out_mem; + if (fid < HI_FID_TABLE_BOTTOM) { + if (cntlofreq) { + /* if both entries are the same, ignore this + * one... + */ + if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || + (powernow_table[i].index != powernow_table[cntlofreq].index)) { + printk(KERN_ERR PFX "Too many lo freq table entries\n"); + goto err_out_mem; + } + + dprintk(KERN_INFO PFX "double low frequency table entry, ignoring it.\n"); + powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; + continue; + } else + cntlofreq = i; } if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { @@ -857,12 +869,9 @@ if (smp_processor_id() != pol->cpu) { printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); - goto sched_out; + goto err_out; } - /* from this point, do not exit without restoring preempt and cpu */ - preempt_disable(); - if (pending_bit_stuck()) { printk(KERN_ERR PFX "failing targ, change pending bit set\n"); goto err_out; @@ -900,8 +909,6 @@ ret = 0; err_out: - preempt_enable_no_resched(); -sched_out: set_cpus_allowed(current, oldmask); schedule(); diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-06-15 23:10:00.080867431 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 2004-06-15 23:10:23.675860651 -0700 @@ -67,28 +67,19 @@ /** * speedstep_set_state - set the SpeedStep state * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * @notify: whether to call cpufreq_notify_transition for CPU speed changes * * Tries to change the SpeedStep state. */ -static void speedstep_set_state (unsigned int state, unsigned int notify) +static void speedstep_set_state (unsigned int state) { u32 pmbase; u8 pm2_blk; u8 value; unsigned long flags; - struct cpufreq_freqs freqs; if (!speedstep_chipset_dev || (state > 0x1)) return; - freqs.old = speedstep_get_processor_frequency(speedstep_processor); - freqs.new = speedstep_freqs[state].frequency; - freqs.cpu = 0; /* speedstep.c is UP only driver */ - - if (notify) - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - /* get PMBASE */ pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); if (!(pmbase & 0x01)) @@ -143,9 +134,6 @@ printk (KERN_ERR "cpufreq: change failed - I/O error\n"); } - if (notify) - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - return; } @@ -252,11 +240,47 @@ unsigned int relation) { unsigned int newstate = 0; + struct cpufreq_freqs freqs; + cpumask_t cpus_allowed, affected_cpu_map; + int i; if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) return -EINVAL; - speedstep_set_state(newstate, 1); + /* no transition necessary */ + if (freqs.old == freqs.new) + return 0; + + freqs.old = speedstep_get_processor_frequency(speedstep_processor); + freqs.new = speedstep_freqs[newstate].frequency; + freqs.cpu = policy->cpu; + + cpus_allowed = current->cpus_allowed; + + /* only run on CPU to be set, or on its sibling */ +#ifdef CONFIG_SMP + affected_cpu_map = cpu_sibling_map[policy->cpu]; +#else + affected_cpu_map = cpumask_of_cpu(policy->cpu); +#endif + + for_each_cpu_mask(i, affected_cpu_map) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + } + + /* switch to physical CPU where state is to be changed */ + set_cpus_allowed(current, affected_cpu_map); + + speedstep_set_state(newstate); + + /* allow to be run on all CPUs */ + set_cpus_allowed(current, cpus_allowed); + + for_each_cpu_mask(i, affected_cpu_map) { + freqs.cpu = i; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + } return 0; } @@ -279,21 +303,35 @@ { int result = 0; unsigned int speed; + cpumask_t cpus_allowed,affected_cpu_map; + /* capability check */ - if (policy->cpu != 0) + if (policy->cpu != 0) /* FIXME: better support for SMT in cpufreq core. Up until then, it's better to register only one CPU */ return -ENODEV; + /* only run on CPU to be set, or on its sibling */ + cpus_allowed = current->cpus_allowed; +#ifdef CONFIG_SMP + affected_cpu_map = cpu_sibling_map[policy->cpu]; +#else + affected_cpu_map = cpumask_of_cpu(policy->cpu); +#endif + set_cpus_allowed(current, affected_cpu_map); + /* detect low and high frequency */ result = speedstep_get_freqs(speedstep_processor, &speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency, &speedstep_set_state); - if (result) + if (result) { + set_cpus_allowed(current, cpus_allowed); return result; + } /* get current speed setting */ speed = speedstep_get_processor_frequency(speedstep_processor); + set_cpus_allowed(current, cpus_allowed); if (!speed) return -EIO; diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c 2004-06-15 23:10:23.675860651 -0700 @@ -252,11 +252,10 @@ * specific. * M-P4-Ms may have either ebx=0xe or 0xf [see above] * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf] - * So, how to distinguish all those processors with - * ebx=0xf? I don't know. Sort them out, and wait - * for someone to complain. + * also, M-P4M HTs have ebx=0x8, too + * For now, they are distinguished by the model_id string */ - if (ebx == 0x0e) + if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL)) return SPEEDSTEP_PROCESSOR_P4M; break; default: @@ -321,9 +320,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, unsigned int *low_speed, unsigned int *high_speed, - void (*set_state) (unsigned int state, - unsigned int notify) - ) + void (*set_state) (unsigned int state)) { unsigned int prev_speed; unsigned int ret = 0; @@ -340,7 +337,7 @@ local_irq_save(flags); /* switch to low state */ - set_state(SPEEDSTEP_LOW, 0); + set_state(SPEEDSTEP_LOW); *low_speed = speedstep_get_processor_frequency(processor); if (!*low_speed) { ret = -EIO; @@ -348,7 +345,7 @@ } /* switch to high state */ - set_state(SPEEDSTEP_HIGH, 0); + set_state(SPEEDSTEP_HIGH); *high_speed = speedstep_get_processor_frequency(processor); if (!*high_speed) { ret = -EIO; @@ -362,7 +359,7 @@ /* switch to previous state, if necessary */ if (*high_speed != prev_speed) - set_state(SPEEDSTEP_LOW, 0); + set_state(SPEEDSTEP_LOW); out: local_irq_restore(flags); diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h 2004-06-15 23:10:23.675860651 -0700 @@ -44,4 +44,4 @@ extern unsigned int speedstep_get_freqs(unsigned int processor, unsigned int *low_speed, unsigned int *high_speed, - void (*set_state) (unsigned int state, unsigned int notify)); + void (*set_state) (unsigned int state)); diff -urN linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c --- linux-2.6.7-rc3/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2004-06-15 23:10:00.081867473 -0700 +++ linux-2.6.7/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c 2004-06-15 23:10:23.676860693 -0700 @@ -139,37 +139,24 @@ : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0) ); - return state; + return (state & 1); } /** * speedstep_set_state - set the SpeedStep state * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * @notify: whether to call cpufreq_notify_transition * */ -static void speedstep_set_state (unsigned int state, unsigned int notify) +static void speedstep_set_state (unsigned int state) { - unsigned int old_state, result = 0, command, new_state; + unsigned int result = 0, command, new_state; unsigned long flags; - struct cpufreq_freqs freqs; unsigned int function=SET_SPEEDSTEP_STATE; unsigned int retry = 0; if (state > 0x1) return; - old_state = speedstep_get_state(); - freqs.old = speedstep_freqs[old_state].frequency; - freqs.new = speedstep_freqs[state].frequency; - freqs.cpu = 0; /* speedstep.c is UP only driver */ - - if (old_state == state) - return; - - if (notify) - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - /* Disable IRQs */ local_irq_save(flags); @@ -198,9 +185,6 @@ printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result); } - if (notify) - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - return; } @@ -217,11 +201,21 @@ unsigned int target_freq, unsigned int relation) { unsigned int newstate = 0; + struct cpufreq_freqs freqs; if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) return -EINVAL; - speedstep_set_state(newstate, 1); + freqs.old = speedstep_freqs[speedstep_get_state()].frequency; + freqs.new = speedstep_freqs[newstate].frequency; + freqs.cpu = 0; /* speedstep.c is UP only driver */ + + if (freqs.old == freqs.new) + return 0; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + speedstep_set_state(newstate); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return 0; } diff -urN linux-2.6.7-rc3/arch/i386/kernel/process.c linux-2.6.7/arch/i386/kernel/process.c --- linux-2.6.7-rc3/arch/i386/kernel/process.c 2004-06-15 23:10:00.090867852 -0700 +++ linux-2.6.7/arch/i386/kernel/process.c 2004-06-15 23:10:23.686861114 -0700 @@ -202,7 +202,7 @@ if (!strncmp(str, "poll", 4)) { printk("using polling idle threads.\n"); pm_idle = poll_idle; -#ifdef CONFIG_SMP +#ifdef CONFIG_X86_SMP if (smp_num_siblings > 1) printk("WARNING: polling idle and HT enabled, performance may degrade.\n"); #endif diff -urN linux-2.6.7-rc3/arch/i386/kernel/timers/timer_cyclone.c linux-2.6.7/arch/i386/kernel/timers/timer_cyclone.c --- linux-2.6.7-rc3/arch/i386/kernel/timers/timer_cyclone.c 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/i386/kernel/timers/timer_cyclone.c 2004-06-15 23:10:23.690861282 -0700 @@ -17,6 +17,7 @@ #include #include #include +#include "io_ports.h" extern spinlock_t i8253_lock; @@ -62,6 +63,17 @@ count = inb_p(0x40); /* read the latched count */ count |= inb(0x40) << 8; + + /* + * VIA686a test code... reset the latch if count > max + 1 + * from timer_pit.c - cjb + */ + if (count > LATCH) { + outb_p(0x34, PIT_MODE); + outb_p(LATCH & 0xff, PIT_CH0); + outb(LATCH >> 8, PIT_CH0); + count = LATCH - 1; + } spin_unlock(&i8253_lock); /* lost tick compensation */ diff -urN linux-2.6.7-rc3/arch/i386/mach-es7000/es7000plat.c linux-2.6.7/arch/i386/mach-es7000/es7000plat.c --- linux-2.6.7-rc3/arch/i386/mach-es7000/es7000plat.c 2004-06-15 23:10:00.101868315 -0700 +++ linux-2.6.7/arch/i386/mach-es7000/es7000plat.c 2004-06-15 23:10:23.697861577 -0700 @@ -50,7 +50,6 @@ struct mip_reg *host_reg; int mip_port; unsigned long mip_addr, host_addr; -extern int (*platform_rename_gsi)(); static int __init es7000_rename_gsi(int ioapic, int gsi) @@ -134,7 +133,6 @@ } if (success < 2) { - printk("\nNo ES7000 found.\n"); es7000_plat = 0; } else { printk("\nEnabling ES7000 specific features...\n"); diff -urN linux-2.6.7-rc3/arch/ia64/kernel/fsys.S linux-2.6.7/arch/ia64/kernel/fsys.S --- linux-2.6.7-rc3/arch/ia64/kernel/fsys.S 2004-06-15 23:10:00.121869156 -0700 +++ linux-2.6.7/arch/ia64/kernel/fsys.S 2004-06-15 23:10:23.716862377 -0700 @@ -502,6 +502,7 @@ adds r17=-1024,r15 movl r14=sys_call_table ;; + rsm psr.i shladd r18=r17,3,r14 ;; ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point @@ -542,7 +543,7 @@ * to synthesize. */ # define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ - | IA64_PSR_BN) + | IA64_PSR_BN | IA64_PSR_I) invala movl r8=PSR_ONE_BITS diff -urN linux-2.6.7-rc3/arch/ia64/kernel/gate.S linux-2.6.7/arch/ia64/kernel/gate.S --- linux-2.6.7-rc3/arch/ia64/kernel/gate.S 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/arch/ia64/kernel/gate.S 2004-06-15 23:10:23.716862377 -0700 @@ -91,16 +91,18 @@ cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? ;; (p6) ld8 r18=[r18] - mov r29=psr // read psr (12 cyc load latency) + mov r21=ar.fpsr add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry ;; (p6) mov b7=r18 (p6) tbit.z p8,p0=r18,0 (p8) br.dptk.many b7 +(p6) rsm psr.i mov r27=ar.rsc - mov r21=ar.fpsr mov r26=ar.pfs + ;; + mov r29=psr // read psr (12 cyc load latency) /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some diff -urN linux-2.6.7-rc3/arch/ppc/8260_io/fcc_enet.c linux-2.6.7/arch/ppc/8260_io/fcc_enet.c --- linux-2.6.7-rc3/arch/ppc/8260_io/fcc_enet.c 2004-05-09 19:32:29.000000000 -0700 +++ linux-2.6.7/arch/ppc/8260_io/fcc_enet.c 2004-06-15 23:10:23.973873197 -0700 @@ -158,12 +158,21 @@ #define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV) #define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER) +#ifdef CONFIG_SBC82xx +/* rx is clk9, tx is clk10 + */ +#define PC_F1RXCLK ((uint)0x00000100) +#define PC_F1TXCLK ((uint)0x00000200) +#define CMX1_CLK_ROUTE ((uint)0x25000000) +#define CMX1_CLK_MASK ((uint)0xff000000) +#else /* CLK12 is receive, CLK11 is transmit. These are board specific. */ #define PC_F1RXCLK ((uint)0x00000800) #define PC_F1TXCLK ((uint)0x00000400) #define CMX1_CLK_ROUTE ((uint)0x3e000000) #define CMX1_CLK_MASK ((uint)0xff000000) +#endif /* !CONFIG_SBC82xx */ /* I/O Pin assignment for FCC2. I don't yet know the best way to do this, * but there is little variation among the choices. @@ -288,6 +297,8 @@ ushort skb_cur; ushort skb_dirty; + atomic_t n_pkts; /* Number of packets in tx ring */ + /* CPM dual port RAM relative addresses. */ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ @@ -347,6 +358,7 @@ { struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv; volatile cbd_t *bdp; + int idx; if (!cep->link) { /* Link is down or autonegotiation is in progress. */ @@ -379,13 +391,24 @@ bdp->cbd_datlen = skb->len; bdp->cbd_bufaddr = __pa(skb->data); + spin_lock_irq(&cep->lock); + /* Save skb pointer. */ - cep->tx_skbuff[cep->skb_cur] = skb; + idx = cep->skb_cur & TX_RING_MOD_MASK; + if (cep->tx_skbuff[idx]) { + /* This should never happen (any more). + Leave the sanity check in for now... */ + printk(KERN_ERR "EEP. cep->tx_skbuff[%d] is %p not NULL in %s\n", + idx, cep->tx_skbuff[idx], __func__); + printk(KERN_ERR "Expect to lose %d bytes of sock space", + cep->tx_skbuff[idx]->truesize); + } + cep->tx_skbuff[idx] = skb; cep->stats.tx_bytes += skb->len; - cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK; + cep->skb_cur++; - spin_lock_irq(&cep->lock); + atomic_inc(&cep->n_pkts); /* Send it on its way. Tell CPM its ready, interrupt when done, * its the last BD of the frame, and to put the CRC on the end. @@ -404,9 +427,13 @@ else bdp++; - if (bdp->cbd_sc & BD_ENET_TX_READY) { - netif_stop_queue(dev); + + /* If the tx_ring is full, stop the queue */ + if (atomic_read(&cep->n_pkts) >= (TX_RING_SIZE-1)) { + if (!netif_queue_stopped(dev)) { + netif_stop_queue(dev); cep->tx_full = 1; + } } cep->cur_tx = (cbd_t *)bdp; @@ -460,6 +487,7 @@ volatile cbd_t *bdp; ushort int_events; int must_restart; + int idx; cep = (struct fcc_enet_private *)dev->priv; @@ -522,8 +550,12 @@ cep->stats.collisions++; /* Free the sk buffer associated with this last transmit. */ - dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]); - cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK; + idx = cep->skb_dirty & TX_RING_MOD_MASK; + dev_kfree_skb_irq(cep->tx_skbuff[idx]); + cep->tx_skbuff[idx] = NULL; + cep->skb_dirty++; + + atomic_dec(&cep->n_pkts); /* Update pointer to next buffer descriptor to be transmitted. */ if (bdp->cbd_sc & BD_ENET_TX_WRAP) @@ -1594,11 +1626,21 @@ */ eap = (unsigned char *)&(ep->fen_paddrh); for (i=5; i>=0; i--) { +#ifdef CONFIG_SBC82xx + if (i == 5) { + /* bd->bi_enetaddr holds the SCC0 address; the FCC + devices count up from there */ + dev->dev_addr[i] = bd->bi_enetaddr[i] & ~3; + dev->dev_addr[i] += 1 + fip->fc_fccnum; + *eap++ = dev->dev_addr[i]; + } +#else if (i == 3) { dev->dev_addr[i] = bd->bi_enetaddr[i]; dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum)); *eap++ = dev->dev_addr[i]; } +#endif else { *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i]; } @@ -1683,6 +1725,7 @@ while (cp->cp_cpcr & CPM_CR_FLG); cep->skb_cur = cep->skb_dirty = 0; + atomic_set(&cep->n_pkts, 0); } /* Let 'er rip. diff -urN linux-2.6.7-rc3/arch/ppc/8260_io/uart.c linux-2.6.7/arch/ppc/8260_io/uart.c --- linux-2.6.7-rc3/arch/ppc/8260_io/uart.c 2004-06-15 23:10:00.379880016 -0700 +++ linux-2.6.7/arch/ppc/8260_io/uart.c 2004-06-15 23:10:23.974873239 -0700 @@ -161,7 +161,7 @@ #ifndef CONFIG_SCC1_ENET { 0, 0, PROFF_SCC1, SIU_INT_SCC1, 0, SCC_NUM_BASE}, /* SCC1 ttyS2 */ #endif -#ifndef CONFIG_SCC2_ENET +#if !defined(CONFIG_SBC82xx) && !defined(CONFIG_SCC2_ENET) { 0, 0, PROFF_SCC2, SIU_INT_SCC2, 0, SCC_NUM_BASE + 1}, /* SCC2 ttyS3 */ #endif }; @@ -475,7 +475,7 @@ if (break_pressed && info->line == sercons.index) { if (ch != 0 && time_before(jiffies, break_pressed + HZ*5)) { - handle_sysrq(ch, regs, NULL, NULL); + handle_sysrq(ch, regs, NULL); break_pressed = 0; goto ignore_char; } else diff -urN linux-2.6.7-rc3/arch/ppc/Kconfig linux-2.6.7/arch/ppc/Kconfig --- linux-2.6.7-rc3/arch/ppc/Kconfig 2004-06-15 23:10:00.383880184 -0700 +++ linux-2.6.7/arch/ppc/Kconfig 2004-06-15 23:10:23.979873450 -0700 @@ -542,6 +542,15 @@ , but the EST8260 cannot be found on it and has probably been discontinued or rebadged. +config SBC82xx + bool "SBC82xx" + ---help--- + SBC PowerQUICC II, single-board computer with MPC82xx CPU + Manufacturer: Wind River Systems, Inc. + Date of Release: May 2003 + End of Life: - + URL: + config SBS8260 bool "SBS8260" @@ -575,7 +584,7 @@ config 8260 bool "MPC8260 CPM Support" if WILLOW depends on 6xx - default y if TQM8260 || RPXSUPER || EST8260 || SBS8260 + default y if TQM8260 || RPXSUPER || EST8260 || SBS8260 || SBC82xx help The MPC8260 CPM (Communications Processor Module) is a typical embedded CPU made by Motorola. Selecting this option means that diff -urN linux-2.6.7-rc3/arch/ppc/Makefile linux-2.6.7/arch/ppc/Makefile --- linux-2.6.7-rc3/arch/ppc/Makefile 2004-06-15 23:10:00.384880227 -0700 +++ linux-2.6.7/arch/ppc/Makefile 2004-06-15 23:10:23.980873492 -0700 @@ -86,7 +86,7 @@ ifdef CONFIG_6xx # Ensure this is binutils 2.12.1 (or 2.12.90.0.7) or later -NEW_AS := $(shell echo dssall | $(AS) -o /dev/null >/dev/null 2>&1 ; echo $$?) +NEW_AS := $(shell echo dssall | $(AS) -many -o /dev/null >/dev/null 2>&1 ; echo $$?) GOODVER := 2.12.1 else NEW_AS := 0 @@ -94,7 +94,7 @@ ifneq ($(NEW_AS),0) checkbin: - @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build' + @echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' @echo 'correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to ${GOODVER} or newer' @false diff -urN linux-2.6.7-rc3/arch/ppc/boot/simple/embed_config.c linux-2.6.7/arch/ppc/boot/simple/embed_config.c --- linux-2.6.7-rc3/arch/ppc/boot/simple/embed_config.c 2004-06-15 23:10:00.385880269 -0700 +++ linux-2.6.7/arch/ppc/boot/simple/embed_config.c 2004-06-15 23:10:23.982873576 -0700 @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_8xx #include #endif @@ -402,14 +403,18 @@ #ifdef CONFIG_8260 /* Compute 8260 clock values if the rom doesn't provide them. - * We can't compute the internal core frequency (I don't know how to - * do that). */ +static unsigned char bus2core_8260[] = { +/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, + 6, 5, 13, 2, 14, 4, 15, 2, 3, 11, 8, 10, 16, 12, 7, 2, +}; + static void clk_8260(bd_t *bd) { uint scmr, vco_out, clkin; - uint plldf, pllmf, busdf, brgdf, cpmdf; + uint plldf, pllmf, corecnf; volatile immap_t *ip; ip = (immap_t *)IMAP_ADDR; @@ -423,8 +428,7 @@ */ plldf = (scmr >> 12) & 1; pllmf = scmr & 0xfff; - cpmdf = (scmr >> 16) & 0x0f; - busdf = (scmr >> 20) & 0x0f; + corecnf = (scmr >> 24) &0x1f; /* This is arithmetic from the 8260 manual. */ @@ -433,6 +437,7 @@ bd->bi_vco = vco_out; /* Save for later */ bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ + bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2; /* Set Baud rate divisor. The power up default is divide by 16, * but we set it again here in case it was changed. @@ -440,8 +445,79 @@ ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ bd->bi_brgfreq = vco_out / 16; } + +static unsigned char bus2core_8280[] = { +/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + 3, 2, 2, 2, 4, 4, 5, 9, 6, 11, 8, 10, 3, 12, 7, 2, + 6, 5, 13, 2, 14, 2, 15, 2, 3, 2, 2, 2, 16, 2, 2, 2, +}; + +static void +clk_8280(bd_t *bd) +{ + uint scmr, main_clk, clkin; + uint pllmf, corecnf; + volatile immap_t *ip; + + ip = (immap_t *)IMAP_ADDR; + scmr = ip->im_clkrst.car_scmr; + + /* The clkin is always bus frequency. + */ + clkin = bd->bi_busfreq; + + /* Collect the bits from the scmr. + */ + pllmf = scmr & 0xf; + corecnf = (scmr >> 24) & 0x1f; + + /* This is arithmetic from the 8280 manual. + */ + main_clk = clkin * (pllmf + 1); + + bd->bi_cpmfreq = main_clk / 2; /* CPM Freq, in MHz */ + bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2; + + /* Set Baud rate divisor. The power up default is divide by 16, + * but we set it again here in case it was changed. + */ + ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1; + bd->bi_brgfreq = main_clk / 16; +} #endif +#ifdef CONFIG_SBC82xx +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd; + unsigned long pvr; + + bd = *bdp; + + bd = &bdinfo; + *bdp = bd; + bd->bi_baudrate = 9600; + bd->bi_memsize = 256 * 1024 * 1024; /* just a guess */ + + cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1; + memcpy(bd->bi_enetaddr, cp, 6); + + /* can busfreq be calculated? */ + pvr = mfspr(PVR); + if ((pvr & 0xffff0000) == 0x80820000) { + bd->bi_busfreq = 100000000; + clk_8280(bd); + } else { + bd->bi_busfreq = 66000000; + clk_8260(bd); + } + +} +#endif /* SBC82xx */ + #if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260) void embed_config(bd_t **bdp) diff -urN linux-2.6.7-rc3/arch/ppc/kernel/cputable.c linux-2.6.7/arch/ppc/kernel/cputable.c --- linux-2.6.7-rc3/arch/ppc/kernel/cputable.c 2004-06-15 23:10:00.411881363 -0700 +++ linux-2.6.7/arch/ppc/kernel/cputable.c 2004-06-15 23:10:24.007874628 -0700 @@ -350,6 +350,14 @@ 32, 32, __setup_cpu_603 }, + { /* 8280 is a G2_LE (603e core, plus some) */ + 0x7fff0000, 0x00820000, "8280", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, { /* default match, we assume split I/D cache & TB (non-601)... */ 0x00000000, 0x00000000, "(generic PPC)", CPU_FTR_COMMON | diff -urN linux-2.6.7-rc3/arch/ppc/platforms/Makefile linux-2.6.7/arch/ppc/platforms/Makefile --- linux-2.6.7-rc3/arch/ppc/platforms/Makefile 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/arch/ppc/platforms/Makefile 2004-06-15 23:10:24.045876228 -0700 @@ -45,6 +45,7 @@ obj-$(CONFIG_PRPMC750) += prpmc750.o obj-$(CONFIG_PRPMC800) += prpmc800.o obj-$(CONFIG_SANDPOINT) += sandpoint.o +obj-$(CONFIG_SBC82xx) += sbc82xx.o obj-$(CONFIG_SPRUCE) += spruce.o ifeq ($(CONFIG_SMP),y) diff -urN linux-2.6.7-rc3/arch/ppc/platforms/sbc82xx.c linux-2.6.7/arch/ppc/platforms/sbc82xx.c --- linux-2.6.7-rc3/arch/ppc/platforms/sbc82xx.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/arch/ppc/platforms/sbc82xx.c 2004-06-15 23:10:24.048876355 -0700 @@ -0,0 +1,113 @@ +/* + * arch/ppc/platforms/sbc82xx.c + * + * SBC82XX platform support + * + * Author: Guy Streeter + * + * Derived from: est8260_setup.c by Allen Curtis, ONZ + * + * Copyright 2004 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void (*callback_setup_arch)(void); + +extern unsigned char __res[sizeof(bd_t)]; + +extern void m8260_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7); + +extern void (*late_time_init)(void); + +static int +sbc82xx_show_cpuinfo(struct seq_file *m) +{ + bd_t *binfo = (bd_t *)__res; + + seq_printf(m, "vendor\t\t: Wind River\n" + "machine\t\t: SBC PowerQUICC II\n" + "\n" + "mem size\t\t: 0x%08lx\n" + "console baud\t\t: %ld\n" + "\n", + binfo->bi_memsize, + binfo->bi_baudrate); + return 0; +} + +static void __init +sbc82xx_setup_arch(void) +{ + printk("SBC PowerQUICC II Port\n"); + callback_setup_arch(); +} + +TODC_ALLOC(); + +/* + * Timer init happens before mem_init but after paging init, so we cannot + * directly use ioremap() at that time. + * late_time_init() is call after paging init. + */ +#ifdef CONFIG_GEN_RTC +static void sbc82xx_time_init(void) +{ + volatile memctl8260_t *mc = &immr->im_memctl; + TODC_INIT(TODC_TYPE_MK48T59, 0, 0, SBC82xx_TODC_NVRAM_ADDR, 0); + + /* Set up CS11 for RTC chip */ + mc->memc_br11=0; + mc->memc_or11=0xffff0836; + mc->memc_br11=0x80000801; + + todc_info->nvram_data = + (unsigned int)ioremap(todc_info->nvram_data, 0x2000); + BUG_ON(!todc_info->nvram_data); + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + todc_time_init(); +} +#endif /* CONFIG_GEN_RTC */ + +void __init +platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* Generic 8260 platform initialization */ + m8260_init(r3, r4, r5, r6, r7); + + /* u-boot may be using one of the FCC Ethernet devices. + Use the MAC address to the SCC. */ + __res[offsetof(bd_t, bi_enetaddr[5])] &= ~3; + + /* Anything special for this platform */ + ppc_md.show_cpuinfo = sbc82xx_show_cpuinfo; + + callback_setup_arch = ppc_md.setup_arch; + ppc_md.setup_arch = sbc82xx_setup_arch; +#ifdef CONFIG_GEN_RTC + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.nvram_read_val = NULL; + ppc_md.nvram_write_val = NULL; + late_time_init = sbc82xx_time_init; +#endif /* CONFIG_GEN_RTC */ +} diff -urN linux-2.6.7-rc3/arch/ppc/platforms/sbc82xx.h linux-2.6.7/arch/ppc/platforms/sbc82xx.h --- linux-2.6.7-rc3/arch/ppc/platforms/sbc82xx.h 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/arch/ppc/platforms/sbc82xx.h 2004-06-15 23:10:24.048876355 -0700 @@ -0,0 +1,24 @@ +/* Board information for the SBCPowerQUICCII, which should be generic for + * all 8260 boards. The IMMR is now given to us so the hard define + * will soon be removed. All of the clock values are computed from + * the configuration SCMR and the Power-On-Reset word. + */ + +#ifndef __PPC_SBC82xx_H__ +#define __PPC_SBC82xx_H__ + +#include + +#define IMAP_ADDR 0xf0000000 +#define CPM_MAP_ADDR 0xf0000000 + +#define SBC82xx_TODC_NVRAM_ADDR 0x80000000 + +#define SBC82xx_MACADDR_NVRAM_FCC1 0x220000c9 /* JP6B */ +#define SBC82xx_MACADDR_NVRAM_SCC1 0x220000cf /* JP6A */ +#define SBC82xx_MACADDR_NVRAM_FCC2 0x220000d5 /* JP7A */ +#define SBC82xx_MACADDR_NVRAM_FCC3 0x220000db /* JP7B */ + +#define BOOTROM_RESTART_ADDR ((uint)0x40000104) + +#endif /* __PPC_SBC82xx_H__ */ diff -urN linux-2.6.7-rc3/arch/ppc/syslib/Makefile linux-2.6.7/arch/ppc/syslib/Makefile --- linux-2.6.7-rc3/arch/ppc/syslib/Makefile 2004-06-15 23:10:00.452883089 -0700 +++ linux-2.6.7/arch/ppc/syslib/Makefile 2004-06-15 23:10:24.049876397 -0700 @@ -63,6 +63,7 @@ obj-$(CONFIG_HARRIER) += harrier.o obj-$(CONFIG_PRPMC800) += open_pic.o indirect_pci.o pci_auto.o obj-$(CONFIG_SANDPOINT) += i8259.o open_pic.o pci_auto.o todc_time.o +obj-$(CONFIG_SBC82xx) += todc_time.o obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ todc_time.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o diff -urN linux-2.6.7-rc3/arch/ppc64/kernel/pmac_feature.c linux-2.6.7/arch/ppc64/kernel/pmac_feature.c --- linux-2.6.7-rc3/arch/ppc64/kernel/pmac_feature.c 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/arch/ppc64/kernel/pmac_feature.c 2004-06-15 23:10:24.065877070 -0700 @@ -343,6 +343,10 @@ PMAC_TYPE_POWERMAC_G5, g5_features, 0, }, + { "RackMac3,1", "XServe G5", + PMAC_TYPE_POWERMAC_G5, g5_features, + 0, + }, }; /* diff -urN linux-2.6.7-rc3/arch/ppc64/kernel/smp.c linux-2.6.7/arch/ppc64/kernel/smp.c --- linux-2.6.7-rc3/arch/ppc64/kernel/smp.c 2004-06-15 23:10:00.478884183 -0700 +++ linux-2.6.7/arch/ppc64/kernel/smp.c 2004-06-15 23:10:24.075877491 -0700 @@ -390,8 +390,7 @@ } /* Fixup atomic count: it exited inside IRQ handler. */ - ((struct task_struct *)paca[lcpu].xCurrent)->thread_info->preempt_count - = 0; + paca[lcpu].xCurrent->thread_info->preempt_count = 0; /* Fixup SLB round-robin so next segment (kernel) goes in segment 0 */ paca[lcpu].xStab_data.next_round_robin = 0; @@ -817,7 +816,7 @@ init_idle(p, cpu); unhash_process(p); - paca[cpu].xCurrent = (u64)p; + paca[cpu].xCurrent = p; current_set[cpu] = p->thread_info; } @@ -869,7 +868,7 @@ /* cpu_possible is set up in prom.c */ cpu_set(boot_cpuid, cpu_online_map); - paca[boot_cpuid].xCurrent = (u64)current; + paca[boot_cpuid].xCurrent = current; current_set[boot_cpuid] = current->thread_info; } diff -urN linux-2.6.7-rc3/arch/ppc64/kernel/traps.c linux-2.6.7/arch/ppc64/kernel/traps.c --- linux-2.6.7-rc3/arch/ppc64/kernel/traps.c 2004-06-15 23:10:00.486884520 -0700 +++ linux-2.6.7/arch/ppc64/kernel/traps.c 2004-06-15 23:10:24.083877828 -0700 @@ -466,6 +466,18 @@ _exception(SIGTRAP, &info, regs); } +/* + * After we have successfully emulated an instruction, we have to + * check if the instruction was being single-stepped, and if so, + * pretend we got a single-step exception. This was pointed out + * by Kumar Gala. -- paulus + */ +static inline void emulate_single_step(struct pt_regs *regs) +{ + if (regs->msr & MSR_SE) + SingleStepException(regs); +} + static void dummy_perf(struct pt_regs *regs) { } @@ -487,10 +499,8 @@ fixed = fix_alignment(regs); if (fixed == 1) { - if (!user_mode(regs)) - PPCDBG(PPCDBG_ALIGNFIXUP, "fix alignment at %lx\n", - regs->nip); regs->nip += 4; /* skip over emulated instruction */ + emulate_single_step(regs); return; } diff -urN linux-2.6.7-rc3/arch/ppc64/kernel/vio.c linux-2.6.7/arch/ppc64/kernel/vio.c --- linux-2.6.7-rc3/arch/ppc64/kernel/vio.c 2004-06-15 23:10:00.486884520 -0700 +++ linux-2.6.7/arch/ppc64/kernel/vio.c 2004-06-15 23:10:24.083877828 -0700 @@ -32,7 +32,9 @@ extern struct subsystem devices_subsys; /* needed for vio_find_name() */ -struct iommu_table *vio_build_iommu_table(struct vio_dev *dev); +static struct iommu_table *vio_build_iommu_table(struct vio_dev *); +static const struct vio_device_id *vio_match_device( + const struct vio_device_id *, const struct vio_dev *); #ifdef CONFIG_PPC_PSERIES static int vio_num_address_cells; @@ -136,15 +138,15 @@ * system is in its list of supported devices. Returns the matching * vio_device_id structure or NULL if there is no match. */ -const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, +static const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, const struct vio_dev *dev) { DBGENTER(); #ifdef CONFIG_PPC_PSERIES while (ids->type) { - if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) && - device_is_compatible((struct device_node*)dev->archdata, ids->compat)) + if ((strncmp(((struct device_node *)dev->dev.platform_data)->type, ids->type, strlen(ids->type)) == 0) && + device_is_compatible(dev->dev.platform_data, ids->compat)) return ids; ids++; } @@ -263,14 +265,13 @@ DBGENTER(); /* XXX free TCE table */ - of_node_put(viodev->archdata); + of_node_put(viodev->dev.platform_data); kfree(viodev); } static ssize_t viodev_show_devspec(struct device *dev, char *buf) { - struct vio_dev *viodev = to_vio_dev(dev); - struct device_node *of_node = viodev->archdata; + struct device_node *of_node = dev->platform_data; return sprintf(buf, "%s\n", of_node->full_name); } @@ -278,8 +279,7 @@ static ssize_t viodev_show_name(struct device *dev, char *buf) { - struct vio_dev *viodev = to_vio_dev(dev); - struct device_node *of_node = viodev->archdata; + struct device_node *of_node = dev->platform_data; return sprintf(buf, "%s\n", of_node->name); } @@ -290,7 +290,7 @@ * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in - * of_node (archdata) and adds it to the list of virtual devices. + * of_node (dev.platform_data) and adds it to the list of virtual devices. * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ @@ -324,7 +324,7 @@ } memset(viodev, 0, sizeof(struct vio_dev)); - viodev->archdata = (void *)of_node_get(of_node); + viodev->dev.platform_data = of_node_get(of_node); viodev->unit_address = *unit_address; viodev->iommu_table = vio_build_iommu_table(viodev); @@ -380,7 +380,7 @@ */ const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) { - return get_property((struct device_node *)vdev->archdata, (char*)which, length); + return get_property(vdev->dev.platform_data, (char*)which, length); } EXPORT_SYMBOL(vio_get_attribute); @@ -427,7 +427,7 @@ * Returns a pointer to the built tce tree, or NULL if it can't * find property. */ -struct iommu_table * vio_build_iommu_table(struct vio_dev *dev) +static struct iommu_table * vio_build_iommu_table(struct vio_dev *dev) { unsigned int *dma_window; struct iommu_table *newTceTable; @@ -435,7 +435,7 @@ unsigned long size; int dma_window_property_size; - dma_window = (unsigned int *) get_property((struct device_node *)dev->archdata, "ibm,my-dma-window", &dma_window_property_size); + dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size); if(!dma_window) { return NULL; } diff -urN linux-2.6.7-rc3/arch/s390/appldata/appldata_base.c linux-2.6.7/arch/s390/appldata/appldata_base.c --- linux-2.6.7-rc3/arch/s390/appldata/appldata_base.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/s390/appldata/appldata_base.c 2004-06-15 23:10:24.111879007 -0700 @@ -85,9 +85,10 @@ */ static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp); + void __user *buffer, size_t *lenp); static int appldata_interval_handler(ctl_table *ctl, int write, - struct file *filp, void *buffer, + struct file *filp, + void __user *buffer, size_t *lenp); static struct ctl_table_header *appldata_sysctl_header; @@ -192,7 +193,8 @@ * wrapper function for mod_virt_timer(), because smp_call_function_on() * accepts only one parameter. */ -static void appldata_mod_vtimer_wrap(struct appldata_mod_vtimer_args *args) { +static void appldata_mod_vtimer_wrap(void *p) { + struct appldata_mod_vtimer_args *args = p; mod_virt_timer(args->timer, args->expires); } @@ -252,7 +254,7 @@ */ static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { int len, i; char buf[2]; @@ -309,7 +311,7 @@ */ static int appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { int len, i, interval; char buf[16]; @@ -347,7 +349,7 @@ appldata_mod_vtimer_args.expires = per_cpu_interval; smp_call_function_on( - (void *) appldata_mod_vtimer_wrap, + appldata_mod_vtimer_wrap, &appldata_mod_vtimer_args, 0, 1, i); } @@ -370,7 +372,7 @@ */ static int appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { struct appldata_ops *ops = NULL, *tmp_ops; int rc, len, found; diff -urN linux-2.6.7-rc3/arch/s390/kernel/asm-offsets.c linux-2.6.7/arch/s390/kernel/asm-offsets.c --- linux-2.6.7-rc3/arch/s390/kernel/asm-offsets.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/asm-offsets.c 2004-06-15 23:10:24.112879049 -0700 @@ -32,6 +32,7 @@ DEFINE(__TI_cpu, offsetof(struct thread_info, cpu),); DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count),); BLANK(); + DEFINE(__PT_ARGS, offsetof(struct pt_regs, args),); DEFINE(__PT_PSW, offsetof(struct pt_regs, psw),); DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs),); DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2),); diff -urN linux-2.6.7-rc3/arch/s390/kernel/compat_signal.c linux-2.6.7/arch/s390/kernel/compat_signal.c --- linux-2.6.7-rc3/arch/s390/kernel/compat_signal.c 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/compat_signal.c 2004-06-15 23:10:24.115879175 -0700 @@ -53,7 +53,7 @@ asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); -int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) +int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from) { int err; @@ -130,7 +130,8 @@ } asmlinkage int -sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize) +sys32_rt_sigsuspend(struct pt_regs * regs, compat_sigset_t __user *unewset, + size_t sigsetsize) { sigset_t saveset, newset; compat_sigset_t set32; @@ -162,11 +163,11 @@ if (do_signal(regs, &saveset)) return -EINTR; } -} +} asmlinkage long -sys32_sigaction(int sig, const struct old_sigaction32 *act, - struct old_sigaction32 *oact) +sys32_sigaction(int sig, const struct old_sigaction32 __user *act, + struct old_sigaction32 __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -199,9 +200,9 @@ int do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact); -asmlinkage long -sys32_rt_sigaction(int sig, const struct sigaction32 *act, - struct sigaction32 *oact, size_t sigsetsize) +asmlinkage long +sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, + struct sigaction32 __user *oact, size_t sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -258,7 +259,8 @@ } asmlinkage long -sys32_sigaltstack(const stack_t32 *uss, stack_t32 *uoss, struct pt_regs *regs) +sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss, + struct pt_regs *regs) { stack_t kss, koss; int ret, err = 0; @@ -275,7 +277,9 @@ } set_fs (KERNEL_DS); - ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, regs->gprs[15]); + ret = do_sigaltstack((stack_t __user *) (uss ? &kss : NULL), + (stack_t __user *) (uoss ? &koss : NULL), + regs->gprs[15]); set_fs (old_fs); if (!ret && uoss) { @@ -290,7 +294,7 @@ return ret; } -static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) +static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs) { _s390_regs_common32 regs32; int err, i; @@ -311,7 +315,7 @@ sizeof(_s390_fp_regs32)); } -static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) +static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) { _s390_regs_common32 regs32; int err, i; @@ -343,7 +347,7 @@ asmlinkage long sys32_sigreturn(struct pt_regs *regs) { - sigframe32 *frame = (sigframe32 *)regs->gprs[15]; + sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15]; sigset_t set; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -365,11 +369,11 @@ badframe: force_sig(SIGSEGV, current); return 0; -} +} asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) { - rt_sigframe32 *frame = (rt_sigframe32 *)regs->gprs[15]; + rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15]; sigset_t set; stack_t st; __u32 ss_sp; @@ -399,8 +403,8 @@ /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - set_fs (KERNEL_DS); - do_sigaltstack(&st, NULL, regs->gprs[15]); + set_fs (KERNEL_DS); + do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]); set_fs (old_fs); return regs->gprs[2]; @@ -418,7 +422,7 @@ /* * Determine which stack to use.. */ -static inline void * +static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { unsigned long sp; @@ -439,7 +443,7 @@ sp = (unsigned long) ka->sa.sa_restorer; } - return (void *)((sp - frame_size) & -8ul); + return (void __user *)((sp - frame_size) & -8ul); } static inline int map_signal(int sig) @@ -455,7 +459,7 @@ static void setup_frame32(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) { - sigframe32 *frame = get_sigframe(ka, regs, sizeof(sigframe32)); + sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32)); if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32))) goto give_sigsegv; @@ -474,12 +478,12 @@ } else { regs->gprs[14] = (__u64) frame->retcode; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, - (u16 *)(frame->retcode))) + (u16 __user *)(frame->retcode))) goto give_sigsegv; } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (unsigned int *) frame)) + if (__put_user(regs->gprs[15], (unsigned int __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */ @@ -505,7 +509,7 @@ sigset_t *set, struct pt_regs * regs) { int err = 0; - rt_sigframe32 *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); + rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32)); if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32))) goto give_sigsegv; @@ -531,11 +535,11 @@ } else { regs->gprs[14] = (__u64) frame->retcode; err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, - (u16 *)(frame->retcode)); + (u16 __user *)(frame->retcode)); } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (unsigned int *) frame)) + if (__put_user(regs->gprs[15], (unsigned int __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */ diff -urN linux-2.6.7-rc3/arch/s390/kernel/compat_wrapper.S linux-2.6.7/arch/s390/kernel/compat_wrapper.S --- linux-2.6.7-rc3/arch/s390/kernel/compat_wrapper.S 2004-06-15 23:10:00.518885867 -0700 +++ linux-2.6.7/arch/s390/kernel/compat_wrapper.S 2004-06-15 23:10:24.116879217 -0700 @@ -1097,6 +1097,8 @@ lgfr %r4,%r4 # int llgtr %r5,%r5 # struct compat_timespec * llgtr %r6,%r6 # u32 * + lgf %r0,164(%r15) # int + stg %r0,160(%r15) jg compat_sys_futex # branch to system call .globl sys32_setxattr_wrapper diff -urN linux-2.6.7-rc3/arch/s390/kernel/debug.c linux-2.6.7/arch/s390/kernel/debug.c --- linux-2.6.7-rc3/arch/s390/kernel/debug.c 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/debug.c 2004-06-15 23:10:24.117879260 -0700 @@ -62,9 +62,9 @@ /* internal function prototyes */ static int debug_init(void); -static ssize_t debug_output(struct file *file, char *user_buf, +static ssize_t debug_output(struct file *file, char __user *user_buf, size_t user_len, loff_t * offset); -static ssize_t debug_input(struct file *file, const char *user_buf, +static ssize_t debug_input(struct file *file, const char __user *user_buf, size_t user_len, loff_t * offset); static int debug_open(struct inode *inode, struct file *file); static int debug_close(struct inode *inode, struct file *file); @@ -74,10 +74,10 @@ static int debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf); static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, - struct file *file, const char *user_buf, + struct file *file, const char __user *user_buf, size_t user_buf_size, loff_t * offset); static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, - struct file *file, const char *user_buf, + struct file *file, const char __user *user_buf, size_t user_buf_size, loff_t * offset); static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, char *out_buf, const char *in_buf); @@ -416,10 +416,10 @@ * - copies formated debug entries to the user buffer */ -static ssize_t debug_output(struct file *file, /* file descriptor */ - char *user_buf, /* user buffer */ - size_t len, /* length of buffer */ - loff_t *offset /* offset in the file */ ) +static ssize_t debug_output(struct file *file, /* file descriptor */ + char __user *user_buf, /* user buffer */ + size_t len, /* length of buffer */ + loff_t *offset) /* offset in the file */ { size_t count = 0; size_t entry_offset, size = 0; @@ -462,7 +462,7 @@ */ static ssize_t debug_input(struct file *file, - const char *user_buf, size_t length, + const char __user *user_buf, size_t length, loff_t *offset) { int rc = 0; @@ -942,7 +942,7 @@ */ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view, - struct file *file, const char *user_buf, + struct file *file, const char __user *user_buf, size_t in_buf_size, loff_t * offset) { char input_buf[1]; @@ -1004,9 +1004,9 @@ /* * view function: flushes debug areas */ - + static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, - struct file *file, const char *user_buf, + struct file *file, const char __user *user_buf, size_t in_buf_size, loff_t * offset) { char input_buf[1]; diff -urN linux-2.6.7-rc3/arch/s390/kernel/entry.S linux-2.6.7/arch/s390/kernel/entry.S --- linux-2.6.7-rc3/arch/s390/kernel/entry.S 2004-06-15 23:10:00.518885867 -0700 +++ linux-2.6.7/arch/s390/kernel/entry.S 2004-06-15 23:10:24.118879302 -0700 @@ -24,7 +24,8 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 @@ -47,7 +48,8 @@ SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE -_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) +_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ + _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) #define BASED(name) name-system_call(%r13) @@ -229,13 +231,16 @@ lh %r7,0x8a # get svc number from lowcore sysc_enter: GET_THREAD_INFO # load pointer to task_struct to R9 +sysc_do_svc: sla %r7,2 # *4 and test for svc 0 - bnz BASED(sysc_do_restart) # svc number > 0 + bnz BASED(sysc_nr_ok) # svc number > 0 # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) - bnl BASED(sysc_do_restart) + bnl BASED(sysc_nr_ok) lr %r7,%r1 # copy svc number to %r7 sla %r7,2 # *4 +sysc_nr_ok: + mvc SP_ARGS(4,%r15),SP_R7(%r15) sysc_do_restart: tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. @@ -262,7 +267,6 @@ bz BASED(sysc_leave) # there is no work to do # # One of the work bits is on. Find out which one. -# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED # sysc_work: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED @@ -271,6 +275,8 @@ bo BASED(sysc_sigpending) tm __TI_flags+3(%r9),_TIF_RESTART_SVC bo BASED(sysc_restart) + tm __TI_flags+3(%r9),_TIF_SINGLE_STEP + bo BASED(sysc_singlestep) b BASED(sysc_leave) # @@ -304,6 +310,17 @@ lm %r2,%r6,SP_R2(%r15) # load svc arguments b BASED(sysc_do_restart) # restart svc +# +# _TIF_SINGLE_STEP is set, call do_debugger_trap +# +sysc_singlestep: + ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check + la %r2,SP_PTREGS(%r15) # address of register-save area + l %r1,BASED(.Lhandle_per) # load adr. of per handler + la %r14,BASED(sysc_return) # load adr. of system return + br %r1 # branch to do_debugger_trap + __critical_end: # @@ -495,71 +512,15 @@ # pgm_svcper: SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 - lh %r7,0x8a # get svc number from lowcore - GET_THREAD_INFO # load pointer to task_struct to R9 + lh %r7,0x8a # get svc number from lowcore + GET_THREAD_INFO # load pointer to task_struct to R9 l %r1,__TI_task(%r9) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID - stosm 24(%r15),0x03 # reenable interrupts - sla %r7,2 # *4 and test for svc 0 - bnz BASED(pgm_svcstd) # svc number > 0 ? - # svc 0: system call number in %r1 - cl %r1,BASED(.Lnr_syscalls) - bnl BASED(pgm_svcstd) - lr %r7,%r1 # copy svc number to %r7 - sla %r7,2 # *4 -pgm_svcstd: - tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. - bnz BASED(pgm_tracesys) - basr %r14,%r8 # call sys_xxxx - st %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! - -pgm_svcret: - tm __TI_flags+3(%r9),_TIF_SIGPENDING - bno BASED(pgm_svcper_nosig) - la %r2,SP_PTREGS(%r15) # load pt_regs - sr %r3,%r3 # clear *oldset - l %r1,BASED(.Ldo_signal) - basr %r14,%r1 # call do_signal - -pgm_svcper_nosig: - mvi SP_TRAP+3(%r15),0x28 # set trap indication to pgm check - la %r2,SP_PTREGS(15) # address of register-save area - l %r1,BASED(.Lhandle_per) # load adr. of per handler - la %r14,BASED(sysc_return) # load adr. of system return - br %r1 # branch to do_debugger_trap -# -# call trace before and after sys_call -# -pgm_tracesys: - l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs - la %r3,0 - srl %r7,2 - st %r7,SP_R2(%r15) - basr %r14,%r1 - clc SP_R2(4,%r15),BASED(.Lnr_syscalls) - bnl BASED(pgm_svc_nogo) - l %r7,SP_R2(%r15) # strace changed the syscall - sll %r7,2 - l %r8,sys_call_table-system_call(%r7,%r13) -pgm_svc_go: - lm %r3,%r6,SP_R3(%r15) - l %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - st %r2,SP_R2(%r15) # store return value -pgm_svc_nogo: - tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - bz BASED(pgm_svcret) - l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs - la %r3,1 - la %r14,BASED(pgm_svcret) - br %r1 + oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + stosm 24(%r15),0x03 # reenable interrupts + b BASED(sysc_do_svc) /* * IO interrupt handler routine diff -urN linux-2.6.7-rc3/arch/s390/kernel/entry64.S linux-2.6.7/arch/s390/kernel/entry64.S --- linux-2.6.7-rc3/arch/s390/kernel/entry64.S 2004-06-15 23:10:00.519885909 -0700 +++ linux-2.6.7/arch/s390/kernel/entry64.S 2004-06-15 23:10:24.119879344 -0700 @@ -24,7 +24,8 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 @@ -47,7 +48,8 @@ SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE -_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_RESTART_SVC) +_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ + _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) /* @@ -213,14 +215,17 @@ llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore sysc_enter: GET_THREAD_INFO # load pointer to task_struct to R9 +sysc_do_svc: slag %r7,%r7,2 # *4 and test for svc 0 - jnz sysc_do_restart + jnz sysc_nr_ok # svc 0: system call number in %r1 lghi %r0,NR_syscalls clr %r1,%r0 - jnl sysc_do_restart + jnl sysc_nr_ok lgfr %r7,%r1 # clear high word in r1 slag %r7,%r7,2 # svc 0: system call number in %r1 +sysc_nr_ok: + mvc SP_ARGS(8,%r15),SP_R7(%r15) sysc_do_restart: larl %r10,sys_call_table #ifdef CONFIG_S390_SUPPORT @@ -254,7 +259,6 @@ jz sysc_leave # there is no work to do # # One of the work bits is on. Find out which one. -# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED # sysc_work: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED @@ -263,6 +267,8 @@ jo sysc_sigpending tm __TI_flags+7(%r9),_TIF_RESTART_SVC jo sysc_restart + tm __TI_flags+7(%r9),_TIF_SINGLE_STEP + jo sysc_singlestep j sysc_leave # @@ -294,6 +300,17 @@ lmg %r2,%r6,SP_R2(%r15) # load svc arguments j sysc_do_restart # restart svc +# +# _TIF_SINGLE_STEP is set, call do_debugger_trap +# +sysc_singlestep: + ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + mvi SP_TRAP+1(%r15),0x28 # set trap indication to pgm check + la %r2,SP_PTREGS(%r15) # address of register-save area + larl %r14,sysc_return # load adr. of system return + jg do_debugger_trap # branch to do_debugger_trap + + __critical_end: # @@ -528,75 +545,15 @@ # pgm_svcper: SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore - GET_THREAD_INFO # load pointer to task_struct to R9 + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + GET_THREAD_INFO # load pointer to task_struct to R9 lg %r1,__TI_task(%r9) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID - stosm 48(%r15),0x03 # reenable interrupts - slag %r7,%r7,2 # *4 and test for svc 0 - jnz pgm_svcstd - # svc 0: system call number in %r1 - lghi %r0,NR_syscalls - clr %r1,%r0 - slag %r7,%r1,2 -pgm_svcstd: - larl %r10,sys_call_table -#ifdef CONFIG_S390_SUPPORT - tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ? - jo pgm_svcper_noemu - larl %r10,sys_call_table_emu # use 31 bit emulation system calls -pgm_svcper_noemu: -#endif - tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - lgf %r8,0(%r7,%r10) # load address of system call routine - jnz pgm_tracesys - basr %r14,%r8 # call sys_xxxx - stg %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! - -pgm_svcret: - tm __TI_flags+7(%r9),_TIF_SIGPENDING - jno pgm_svcper_nosig - la %r2,SP_PTREGS(%r15) # load pt_regs - sgr %r3,%r3 # clear *oldset - brasl %r14,do_signal - -pgm_svcper_nosig: - lhi %r0,__LC_PGM_OLD_PSW # set trap indication back to pgm_chk - st %r0,SP_TRAP(%r15) - la %r2,SP_PTREGS(15) # address of register-save area - larl %r14,sysc_return # load adr. of system return - jg do_debugger_trap -# -# call trace before and after sys_call -# -pgm_tracesys: - la %r2,SP_PTREGS(%r15) # load pt_regs - la %r3,0 - srlg %r7,%r7,2 - stg %r7,SP_R2(%r15) - brasl %r14,syscall_trace - lghi %r0,NR_syscalls - clg %r0,SP_R2(%r15) - jnh pgm_svc_nogo - lg %r7,SP_R2(%r15) - sllg %r7,%r7,2 # strace wants to change the syscall - lgf %r8,0(%r7,%r10) -pgm_svc_go: - lmg %r3,%r6,SP_R3(%r15) - lg %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - stg %r2,SP_R2(%r15) # store return value -pgm_svc_nogo: - tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - jz pgm_svcret - la %r2,SP_PTREGS(%r15) # load pt_regs - la %r3,1 - larl %r14,pgm_svcret # return point is sysc_return - jg syscall_trace + oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + stosm 48(%r15),0x03 # reenable interrupts + j sysc_do_svc /* * IO interrupt handler routine diff -urN linux-2.6.7-rc3/arch/s390/kernel/head.S linux-2.6.7/arch/s390/kernel/head.S --- linux-2.6.7-rc3/arch/s390/kernel/head.S 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/head.S 2004-06-15 23:10:24.120879386 -0700 @@ -478,9 +478,80 @@ mvcle %r2,%r4,0 # clear mem jo .-4 # branch back, if not finish + l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word +.Lservicecall: + stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts + + stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0 + la %r1,0x200 # set bit 22 + o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 + st %r1,.Lcr-.LPG1(%r13) + lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0 + + mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw + la %r1, .Lsclph-.LPG1(%r13) + a %r1,__LC_EXT_NEW_PSW+4 # set handler + st %r1,__LC_EXT_NEW_PSW+4 + + la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff + la %r1, .Lsccb-PARMAREA(%r4) # our sccb + .insn rre,0xb2200000,%r2,%r1 # service call + ipm %r1 + srl %r1,28 # get cc code + xr %r3, %r3 + chi %r1,3 + be .Lfchunk-.LPG1(%r13) # leave + chi %r1,2 + be .Lservicecall-.LPG1(%r13) + lpsw .Lwaitsclp-.LPG1(%r13) +.Lsclph: + lh %r1,.Lsccbr-PARMAREA(%r4) + chi %r1,0x10 # 0x0010 is the sucess code + je .Lprocsccb # let's process the sccb + chi %r1,0x1f0 + bne .Lfchunk-.LPG1(%r13) # unhandled error code + c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced + bne .Lfchunk-.LPG1(%r13) # if no, give up + l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP + b .Lservicecall-.LPG1(%r13) +.Lprocsccb: + lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + chi %r1,0x00 + jne .Lscnd + l %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one +.Lscnd: + xr %r3,%r3 # same logic + ic %r3,.Lscpa1-PARMAREA(%r4) + chi %r3,0x00 + jne .Lcompmem + l %r3,.Lscpa2-PARMAREA(%r13) +.Lcompmem: + mr %r2,%r1 # mem in MB on 128-bit + l %r1,.Lonemb-.LPG1(%r13) + mr %r2,%r1 # mem size in bytes in %r3 + b .Lfchunk-.LPG1(%r13) + +.Lpmask: + .byte 0 +.align 8 +.Lpcext:.long 0x00080000,0x80000000 +.Lcr: + .long 0x00 # place holder for cr0 +.Lwaitsclp: + .long 0x020A0000 + .long .Lsclph +.Lrcp: + .int 0x00120001 # Read SCP forced code +.Lrcp2: + .int 0x00020001 # Read SCP code +.Lonemb: + .int 0x100000 +.Lfchunk: + # # find memory chunks. # + lr %r9,%r3 # end of mem mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13) la %r1,1 # test in increments of 128KB sll %r1,17 @@ -488,38 +559,46 @@ slr %r4,%r4 # set start of chunk to zero slr %r5,%r5 # set end of chunk to zero slr %r6,%r6 # set access code to zero + la %r10, MEMORY_CHUNKS # number of chunks .Lloop: tprot 0(%r5),0 # test protection of first byte ipm %r7 srl %r7,28 clr %r6,%r7 # compare cc with last access code be .Lsame-.LPG1(%r13) - clr %r4,%r5 # chunk size > 0? - be .Lsize0-.LPG1(%r13) - st %r4,0(%r3) # store start address of chunk - lr %r0,%r5 - slr %r0,%r4 - st %r0,4(%r3) # store size of chunk - st %r6,8(%r3) # store type of chunk - la %r3,12(%r3) - lr %r4,%r5 # set start to end -.Lsize0: - lr %r6,%r7 # set access code to last cc + b .Lchkmem-.LPG1(%r13) .Lsame: ar %r5,%r1 # add 128KB to end of chunk bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop .Lchkmem: # > 2GB or tprot got a program check clr %r4,%r5 # chunk size > 0? - be .Ldonemem-.LPG1(%r13) + be .Lchkloop-.LPG1(%r13) st %r4,0(%r3) # store start address of chunk lr %r0,%r5 slr %r0,%r4 st %r0,4(%r3) # store size of chunk st %r6,8(%r3) # store type of chunk + la %r3,12(%r3) + l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size + st %r5,0(%r4) # store last end to memory size + ahi %r10,-1 # update chunk number +.Lchkloop: + lr %r6,%r7 # set access code to last cc + # we got an exception or we're starting a new + # chunk , we must check if we should + # still try to find valid memory (if we detected + # the amount of available storage), and if we + # have chunks left + xr %r0,%r0 + clr %r0,%r9 # did we detect memory? + je .Ldonemem # if not, leave + chi %r10,0 # do we have chunks left? + je .Ldonemem + alr %r5,%r1 # add 128KB to end of chunk + lr %r4,%r5 # potential new chunk + clr %r5,%r9 # should we go on? + jl .Lloop .Ldonemem: - l %r1,.Lmemsize-.LPG1(%r13) # address of variable memory_size - st %r5,0(%r1) # store last end to memory size - l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags # # find out if we are running under VM @@ -631,6 +710,23 @@ .byte "root=/dev/ram0 ro" .byte 0 .org 0x11000 +.Lsccb: + .hword 0x1000 # length, one page + .byte 0x00,0x00,0x00 + .byte 0x80 # variable response bit set +.Lsccbr: + .hword 0x00 # response code +.Lscpincr1: + .hword 0x00 +.Lscpa1: + .byte 0x00 + .fill 89,1,0 +.Lscpa2: + .int 0x00 +.Lscpincr2: + .quad 0x00 + .fill 3984,1,0 + .org 0x12000 .global _pend _pend: diff -urN linux-2.6.7-rc3/arch/s390/kernel/head64.S linux-2.6.7/arch/s390/kernel/head64.S --- linux-2.6.7-rc3/arch/s390/kernel/head64.S 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/head64.S 2004-06-15 23:10:24.121879428 -0700 @@ -480,12 +480,81 @@ mvcle %r2,%r4,0 # clear mem jo .-4 # branch back, if not finish + l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word +.Lservicecall: + stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts + + stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 + la %r1,0x200 # set bit 22 + og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 + stg %r1,.Lcr-.LPG1(%r13) + lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 + + mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw + larl %r1,.Lsclph + stg %r1,__LC_EXT_NEW_PSW+8 # set handler + + larl %r4,_pstart # %r4 is our index for sccb stuff + la %r1,.Lsccb-PARMAREA(%r4) # our sccb + .insn rre,0xb2200000,%r2,%r1 # service call + ipm %r1 + srl %r1,28 # get cc code + xr %r3,%r3 + chi %r1,3 + be .Lfchunk-.LPG1(%r13) # leave + chi %r1,2 + be .Lservicecall-.LPG1(%r13) + lpsw .Lwaitsclp-.LPG1(%r13) +.Lsclph: + lh %r1,.Lsccbr-PARMAREA(%r4) + chi %r1,0x10 # 0x0010 is the sucess code + je .Lprocsccb # let's process the sccb + chi %r1,0x1f0 + bne .Lfchunk-.LPG1(%r13) # unhandled error code + c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced + bne .Lfchunk-.LPG1(%r13) # if no, give up + l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP + b .Lservicecall-.LPG1(%r13) +.Lprocsccb: + lh %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + chi %r1,0x00 + jne .Lscnd + lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one +.Lscnd: + xr %r3,%r3 # same logic + ic %r3,.Lscpa1-PARMAREA(%r4) + chi %r3,0x00 + jne .Lcompmem + l %r3,.Lscpa2-PARMAREA(%r13) +.Lcompmem: + mlgr %r2,%r1 # mem in MB on 128-bit + l %r1,.Lonemb-.LPG1(%r13) + mlgr %r2,%r1 # mem size in bytes in %r3 + b .Lfchunk-.LPG1(%r13) + +.Lpmask: + .byte 0 + .align 8 +.Lcr: + .quad 0x00 # place holder for cr0 +.Lwaitsclp: + .long 0x020A0000 + .quad .Lsclph +.Lrcp: + .int 0x00120001 # Read SCP forced code +.Lrcp2: + .int 0x00020001 # Read SCP code +.Lonemb: + .int 0x100000 + +.Lfchunk: # set program check new psw mask mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # # find memory chunks. # + lgr %r9,%r3 # end of mem larl %r1,.Lchkmem # set program check address stg %r1,__LC_PGM_NEW_PSW+8 la %r1,1 # test in increments of 128KB @@ -494,51 +563,51 @@ slgr %r4,%r4 # set start of chunk to zero slgr %r5,%r5 # set end of chunk to zero slr %r6,%r6 # set access code to zero + la %r10,MEMORY_CHUNKS # number of chunks .Lloop: tprot 0(%r5),0 # test protection of first byte ipm %r7 srl %r7,28 clr %r6,%r7 # compare cc with last access code je .Lsame - clgr %r4,%r5 # chunk size > 0? - je .Lsize0 - stg %r4,0(%r3) # store start address of chunk - lgr %r0,%r5 - slgr %r0,%r4 - stg %r0,8(%r3) # store size of chunk - st %r6,20(%r3) # store type of chunk - la %r3,24(%r3) - lgr %r4,%r5 # set start to end - larl %r8,memory_size - stg %r5,0(%r8) # store memory size -.Lsize0: - lr %r6,%r7 # set access code to last cc + j .Lchkmem .Lsame: algr %r5,%r1 # add 128KB to end of chunk - brc 12,.Lloop + # no need to check here, + brc 12,.Lloop # this is the same chunk .Lchkmem: # > 16EB or tprot got a program check clgr %r4,%r5 # chunk size > 0? - je .Ldonemem + je .Lchkloop stg %r4,0(%r3) # store start address of chunk lgr %r0,%r5 slgr %r0,%r4 stg %r0,8(%r3) # store size of chunk st %r6,20(%r3) # store type of chunk la %r3,24(%r3) - lgr %r4,%r5 larl %r8,memory_size stg %r5,0(%r8) # store memory size -# -# Running native the HSA is located at 2GB and we will get an -# addressing exception trying to access it. We have to restart -# the scan at 2GB to find out if the machine has more than 2GB. -# + ahi %r10,-1 # update chunk number +.Lchkloop: + lr %r6,%r7 # set access code to last cc + # we got an exception or we're starting a new + # chunk , we must check if we should + # still try to find valid memory (if we detected + # the amount of available storage), and if we + # have chunks left lghi %r4,1 sllg %r4,%r4,31 clgr %r5,%r4 - jhe .Ldonemem - lgr %r5,%r4 - j .Lloop + je .Lhsaskip + xr %r0, %r0 + clgr %r0, %r9 # did we detect memory? + je .Ldonemem # if not, leave + chi %r10, 0 # do we have chunks left? + je .Ldonemem +.Lhsaskip: + algr %r5,%r1 # add 128KB to end of chunk + lgr %r4,%r5 # potential new chunk + clgr %r5,%r9 # should we go on? + jl .Lloop .Ldonemem: larl %r12,machine_flags @@ -640,6 +709,23 @@ .byte "root=/dev/ram0 ro" .byte 0 .org 0x11000 +.Lsccb: + .hword 0x1000 # length, one page + .byte 0x00,0x00,0x00 + .byte 0x80 # variable response bit set +.Lsccbr: + .hword 0x00 # response code +.Lscpincr1: + .hword 0x00 +.Lscpa1: + .byte 0x00 + .fill 89,1,0 +.Lscpa2: + .int 0x00 +.Lscpincr2: + .quad 0x00 + .fill 3984,1,0 + .org 0x12000 .global _pend _pend: diff -urN linux-2.6.7-rc3/arch/s390/kernel/process.c linux-2.6.7/arch/s390/kernel/process.c --- linux-2.6.7-rc3/arch/s390/kernel/process.c 2004-06-15 23:10:00.520885951 -0700 +++ linux-2.6.7/arch/s390/kernel/process.c 2004-06-15 23:10:24.122879470 -0700 @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -292,12 +293,12 @@ { unsigned long clone_flags; unsigned long newsp; - int *parent_tidptr, *child_tidptr; + int __user *parent_tidptr, *child_tidptr; clone_flags = regs.gprs[3]; newsp = regs.orig_gpr2; - parent_tidptr = (int *) regs.gprs[4]; - child_tidptr = (int *) regs.gprs[5]; + parent_tidptr = (int __user *) regs.gprs[4]; + child_tidptr = (int __user *) regs.gprs[5]; if (!newsp) newsp = regs.gprs[15]; return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, @@ -328,12 +329,12 @@ int error; char * filename; - filename = getname((char *) regs.orig_gpr2); + filename = getname((char __user *) regs.orig_gpr2); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, (char **) regs.gprs[3], - (char **) regs.gprs[4], ®s); + error = do_execve(filename, (char __user * __user *) regs.gprs[3], + (char __user * __user *) regs.gprs[4], ®s); if (error == 0) { current->ptrace &= ~PT_DTRACE; current->thread.fp_regs.fpc = 0; diff -urN linux-2.6.7-rc3/arch/s390/kernel/profile.c linux-2.6.7/arch/s390/kernel/profile.c --- linux-2.6.7-rc3/arch/s390/kernel/profile.c 2004-05-09 19:32:37.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/profile.c 2004-06-15 23:10:24.122879470 -0700 @@ -19,7 +19,8 @@ return len; } -static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, +static int prof_cpu_mask_write_proc (struct file *file, + const char __user *buffer, unsigned long count, void *data) { cpumask_t *mask = (cpumask_t *)data; diff -urN linux-2.6.7-rc3/arch/s390/kernel/ptrace.c linux-2.6.7/arch/s390/kernel/ptrace.c --- linux-2.6.7-rc3/arch/s390/kernel/ptrace.c 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/ptrace.c 2004-06-15 23:10:24.123879512 -0700 @@ -141,7 +141,7 @@ /* * psw and gprs are stored on the stack */ - tmp = *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr); + tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr); if (addr == (addr_t) &dummy->regs.psw.mask) /* Remove per bit from user psw. */ tmp &= ~PSW_MASK_PER; @@ -176,7 +176,7 @@ } else tmp = 0; - return put_user(tmp, (addr_t *) data); + return put_user(tmp, (addr_t __user *) data); } /* @@ -215,7 +215,7 @@ high order bit but older gdb's rely on it */ data |= PSW_ADDR_AMODE; #endif - *(addr_t *)((addr_t) __KSTK_PTREGS(child) + addr) = data; + *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { /* @@ -269,7 +269,7 @@ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); if (copied != sizeof(tmp)) return -EIO; - return put_user(tmp, (unsigned long *) data); + return put_user(tmp, (unsigned long __user *) data); case PTRACE_PEEKUSR: /* read the word at location addr in the USER area. */ @@ -291,7 +291,8 @@ case PTRACE_PEEKUSR_AREA: case PTRACE_POKEUSR_AREA: - if (copy_from_user(&parea, (void *) addr, sizeof(parea))) + if (copy_from_user(&parea, (void __user *) addr, + sizeof(parea))) return -EFAULT; addr = parea.kernel_addr; data = parea.process_addr; @@ -301,7 +302,7 @@ ret = peek_user(child, addr, data); else { addr_t tmp; - if (get_user (tmp, (addr_t *) data)) + if (get_user (tmp, (addr_t __user *) data)) return -EFAULT; ret = poke_user(child, addr, tmp); } @@ -360,7 +361,7 @@ PSW32_ADDR_AMODE31; } else { /* gpr 0-15 */ - tmp = *(__u32 *)((addr_t) __KSTK_PTREGS(child) + + tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw + addr*2 + 4); } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -402,7 +403,7 @@ } else tmp = 0; - return put_user(tmp, (__u32 *) data); + return put_user(tmp, (__u32 __user *) data); } /* @@ -439,8 +440,8 @@ (__u64) tmp & PSW32_ADDR_INSN; } else { /* gpr 0-15 */ - *(__u32*)((addr_t) __KSTK_PTREGS(child) + addr*2 + 4) = - tmp; + *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw + + addr*2 + 4) = tmp; } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { /* @@ -509,7 +510,7 @@ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); if (copied != sizeof(tmp)) return -EIO; - return put_user(tmp, (unsigned int *) data); + return put_user(tmp, (unsigned int __user *) data); case PTRACE_PEEKUSR: /* read the word at location addr in the USER area. */ @@ -530,7 +531,8 @@ case PTRACE_PEEKUSR_AREA: case PTRACE_POKEUSR_AREA: - if (copy_from_user(&parea, (void *) addr, sizeof(parea))) + if (copy_from_user(&parea, (void __user *) addr, + sizeof(parea))) return -EFAULT; addr = parea.kernel_addr; data = parea.process_addr; @@ -540,7 +542,7 @@ ret = peek_user_emu31(child, addr, data); else { __u32 tmp; - if (get_user (tmp, (__u32 *) data)) + if (get_user (tmp, (__u32 __user *) data)) return -EFAULT; ret = poke_user_emu31(child, addr, tmp); } diff -urN linux-2.6.7-rc3/arch/s390/kernel/s390_ksyms.c linux-2.6.7/arch/s390/kernel/s390_ksyms.c --- linux-2.6.7-rc3/arch/s390/kernel/s390_ksyms.c 2004-05-09 19:32:52.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/s390_ksyms.c 2004-06-15 23:10:24.123879512 -0700 @@ -45,25 +45,6 @@ EXPORT_SYMBOL(__down_interruptible); /* - * string functions - */ -EXPORT_SYMBOL_NOVERS(memcmp); -EXPORT_SYMBOL_NOVERS(memset); -EXPORT_SYMBOL_NOVERS(memmove); -EXPORT_SYMBOL_NOVERS(memscan); -EXPORT_SYMBOL_NOVERS(strlen); -EXPORT_SYMBOL_NOVERS(strchr); -EXPORT_SYMBOL_NOVERS(strcmp); -EXPORT_SYMBOL_NOVERS(strncat); -EXPORT_SYMBOL_NOVERS(strncmp); -EXPORT_SYMBOL_NOVERS(strncpy); -EXPORT_SYMBOL_NOVERS(strnlen); -EXPORT_SYMBOL_NOVERS(strrchr); -EXPORT_SYMBOL_NOVERS(strstr); -EXPORT_SYMBOL_NOVERS(strpbrk); -EXPORT_SYMBOL_NOVERS(strcpy); - -/* * binfmt_elf loader */ extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); diff -urN linux-2.6.7-rc3/arch/s390/kernel/setup.c linux-2.6.7/arch/s390/kernel/setup.c --- linux-2.6.7-rc3/arch/s390/kernel/setup.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/setup.c 2004-06-15 23:10:24.124879554 -0700 @@ -53,7 +53,9 @@ unsigned int console_irq = -1; unsigned long memory_size = 0; unsigned long machine_flags = 0; -struct { unsigned long addr, size, type; } memory_chunk[16] = { { 0 } }; +struct { + unsigned long addr, size, type; +} memory_chunk[MEMORY_CHUNKS] = { { 0 } }; #define CHUNK_READ_WRITE 0 #define CHUNK_READ_ONLY 1 int cpus_initialized = 0; diff -urN linux-2.6.7-rc3/arch/s390/kernel/signal.c linux-2.6.7/arch/s390/kernel/signal.c --- linux-2.6.7-rc3/arch/s390/kernel/signal.c 2004-05-09 19:33:12.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/signal.c 2004-06-15 23:10:24.124879554 -0700 @@ -77,8 +77,9 @@ } } -asmlinkage int -sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) +asmlinkage long +sys_rt_sigsuspend(struct pt_regs *regs, sigset_t __user *unewset, + size_t sigsetsize) { sigset_t saveset, newset; @@ -105,9 +106,9 @@ } } -asmlinkage int -sys_sigaction(int sig, const struct old_sigaction *act, - struct old_sigaction *oact) +asmlinkage long +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -137,8 +138,9 @@ return ret; } -asmlinkage int -sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) +asmlinkage long +sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, + struct pt_regs *regs) { return do_sigaltstack(uss, uoss, regs->gprs[15]); } @@ -146,7 +148,7 @@ /* Returns non-zero on fault. */ -static int save_sigregs(struct pt_regs *regs, _sigregs *sregs) +static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { unsigned long old_mask = regs->psw.mask; int err; @@ -175,7 +177,7 @@ } /* Returns positive number on error */ -static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs) +static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { unsigned long old_mask = regs->psw.mask; int err; @@ -208,7 +210,7 @@ asmlinkage long sys_sigreturn(struct pt_regs *regs) { - sigframe *frame = (sigframe *)regs->gprs[15]; + sigframe __user *frame = (sigframe __user *)regs->gprs[15]; sigset_t set; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -234,7 +236,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) { - rt_sigframe *frame = (rt_sigframe *)regs->gprs[15]; + rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; sigset_t set; if (verify_area(VERIFY_READ, frame, sizeof(*frame))) @@ -269,7 +271,7 @@ /* * Determine which stack to use.. */ -static inline void * +static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { unsigned long sp; @@ -290,7 +292,7 @@ sp = (unsigned long) ka->sa.sa_restorer; } - return (void *)((sp - frame_size) & -8ul); + return (void __user *)((sp - frame_size) & -8ul); } static inline int map_signal(int sig) @@ -306,7 +308,9 @@ static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) { - sigframe *frame = get_sigframe(ka, regs, sizeof(sigframe)); + sigframe __user *frame; + + frame = get_sigframe(ka, regs, sizeof(sigframe)); if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe))) goto give_sigsegv; @@ -326,13 +330,13 @@ } else { regs->gprs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; - if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, - (u16 *)(frame->retcode))) + if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, + (u16 __user *)(frame->retcode))) goto give_sigsegv; } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (addr_t *) frame)) + if (__put_user(regs->gprs[15], (addr_t __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */ @@ -358,7 +362,9 @@ sigset_t *set, struct pt_regs * regs) { int err = 0; - rt_sigframe *frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); + rt_sigframe __user *frame; + + frame = get_sigframe(ka, regs, sizeof(rt_sigframe)); if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe))) goto give_sigsegv; @@ -385,12 +391,12 @@ } else { regs->gprs[14] = (unsigned long) frame->retcode | PSW_ADDR_AMODE; - err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, - (u16 *)(frame->retcode)); + err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, + (u16 __user *)(frame->retcode)); } /* Set up backchain. */ - if (__put_user(regs->gprs[15], (addr_t *) frame)) + if (__put_user(regs->gprs[15], (addr_t __user *) frame)) goto give_sigsegv; /* Set up registers for signal handler */ diff -urN linux-2.6.7-rc3/arch/s390/kernel/sys_s390.c linux-2.6.7/arch/s390/kernel/sys_s390.c --- linux-2.6.7-rc3/arch/s390/kernel/sys_s390.c 2004-06-15 23:10:00.521885993 -0700 +++ linux-2.6.7/arch/s390/kernel/sys_s390.c 2004-06-15 23:10:24.126879638 -0700 @@ -37,7 +37,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage long sys_pipe(unsigned long * fildes) +asmlinkage long sys_pipe(unsigned long __user *fildes) { int fd[2]; int error; @@ -92,7 +92,7 @@ unsigned long offset; }; -asmlinkage long sys_mmap2(struct mmap_arg_struct *arg) +asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg) { struct mmap_arg_struct a; int error = -EFAULT; @@ -104,7 +104,7 @@ return error; } -asmlinkage long old_mmap(struct mmap_arg_struct *arg) +asmlinkage long old_mmap(struct mmap_arg_struct __user *arg) { struct mmap_arg_struct a; long error = -EFAULT; @@ -128,7 +128,7 @@ struct timeval *tvp; }; -asmlinkage long old_select(struct sel_arg_struct *arg) +asmlinkage long old_select(struct sel_arg_struct __user *arg) { struct sel_arg_struct a; @@ -145,37 +145,37 @@ * * This is really horribly ugly. */ -asmlinkage long sys_ipc (uint call, int first, int second, - unsigned long third, void *ptr) +asmlinkage long sys_ipc(uint call, int first, int second, + unsigned long third, void __user *ptr) { struct ipc_kludge tmp; int ret; switch (call) { case SEMOP: - return sys_semtimedop (first, (struct sembuf *) ptr, second, + return sys_semtimedop (first, (struct sembuf __user *) ptr, second, NULL); case SEMTIMEDOP: - return sys_semtimedop (first, (struct sembuf *) ptr, second, - (const struct timespec *) third); + return sys_semtimedop (first, (struct sembuf __user *) ptr, second, + (const struct timespec __user *) third); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { union semun fourth; if (!ptr) return -EINVAL; - if (get_user(fourth.__pad, (void **) ptr)) + if (get_user(fourth.__pad, (void __user * __user *) ptr)) return -EFAULT; return sys_semctl (first, second, third, fourth); - } + } case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, + return sys_msgsnd (first, (struct msgbuf __user *) ptr, second, third); break; case MSGRCV: if (!ptr) return -EINVAL; - if (copy_from_user (&tmp, (struct ipc_kludge *) ptr, + if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr, sizeof (struct ipc_kludge))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, @@ -183,33 +183,33 @@ case MSGGET: return sys_msgget ((key_t) first, second); case MSGCTL: - return sys_msgctl (first, second, (struct msqid_ds *) ptr); - + return sys_msgctl (first, second, (struct msqid_ds __user *) ptr); + case SHMAT: { ulong raddr; - ret = do_shmat (first, (char *) ptr, second, &raddr); + ret = do_shmat (first, (char __user *) ptr, second, &raddr); if (ret) return ret; - return put_user (raddr, (ulong *) third); + return put_user (raddr, (ulong __user *) third); break; } - case SHMDT: - return sys_shmdt ((char *)ptr); + case SHMDT: + return sys_shmdt ((char __user *)ptr); case SHMGET: return sys_shmget (first, second, third); case SHMCTL: return sys_shmctl (first, second, - (struct shmid_ds *) ptr); + (struct shmid_ds __user *) ptr); default: return -ENOSYS; } - + return -EINVAL; } #ifdef CONFIG_ARCH_S390X -asmlinkage long s390x_newuname(struct new_utsname * name) +asmlinkage long s390x_newuname(struct new_utsname __user *name) { int ret = sys_newuname(name); @@ -256,7 +256,7 @@ }; asmlinkage long -s390_fadvise64_64(struct fadvise64_64_args *args) +s390_fadvise64_64(struct fadvise64_64_args __user *args) { struct fadvise64_64_args a; diff -urN linux-2.6.7-rc3/arch/s390/kernel/traps.c linux-2.6.7/arch/s390/kernel/traps.c --- linux-2.6.7-rc3/arch/s390/kernel/traps.c 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/arch/s390/kernel/traps.c 2004-06-15 23:10:24.127879681 -0700 @@ -188,7 +188,7 @@ printk("%s Code: ", mode); for (i = 0; i < 20; i++) { unsigned char c; - if (__get_user(c, (char *)(regs->psw.addr + i))) { + if (__get_user(c, (char __user *)(regs->psw.addr + i))) { printk(" Bad PSW."); break; } @@ -391,7 +391,7 @@ local_irq_enable(); if (regs->psw.mask & PSW_MASK_PSTATE) - get_user(*((__u16 *) opcode), location); + get_user(*((__u16 *) opcode), (__u16 __user *)location); else *((__u16 *)opcode)=*((__u16 *)location); if (*((__u16 *)opcode)==S390_BREAKPOINT_U16) diff -urN linux-2.6.7-rc3/arch/s390/lib/Makefile linux-2.6.7/arch/s390/lib/Makefile --- linux-2.6.7-rc3/arch/s390/lib/Makefile 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/Makefile 2004-06-15 23:10:24.127879681 -0700 @@ -4,6 +4,6 @@ EXTRA_AFLAGS := -traditional -lib-y += delay.o -lib-$(CONFIG_ARCH_S390_31) += memset.o strcmp.o strcpy.o strncpy.o uaccess.o -lib-$(CONFIG_ARCH_S390X) += memset64.o strcmp64.o strcpy64.o strncpy64.o uaccess64.o +lib-y += delay.o string.o +lib-$(CONFIG_ARCH_S390_31) += uaccess.o +lib-$(CONFIG_ARCH_S390X) += uaccess64.o diff -urN linux-2.6.7-rc3/arch/s390/lib/memset.S linux-2.6.7/arch/s390/lib/memset.S --- linux-2.6.7-rc3/arch/s390/lib/memset.S 2004-05-09 19:32:39.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/memset.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,30 +0,0 @@ -/* - * arch/s390/lib/memset.S - * S390 fast memset routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address to memory area - * R3 = byte to fill memory with - * R4 = number of bytes to fill - */ - .globl memset -memset: - LTR 4,4 - JZ memset_end - LR 0,2 # save pointer to memory area - LR 1,3 # move pad byte to R1 - LR 3,4 - SR 4,4 # no source for MVCLE, only a pad byte - SR 5,5 - MVCLE 2,4,0(1) # thats it, MVCLE is your friend - JO .-4 - LR 2,0 # return pointer to mem. -memset_end: - BR 14 - - diff -urN linux-2.6.7-rc3/arch/s390/lib/memset64.S linux-2.6.7/arch/s390/lib/memset64.S --- linux-2.6.7-rc3/arch/s390/lib/memset64.S 2004-05-09 19:32:52.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/memset64.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,30 +0,0 @@ -/* - * arch/s390/lib/memset.S - * S390 fast memset routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address to memory area - * R3 = byte to fill memory with - * R4 = number of bytes to fill - */ - .globl memset -memset: - LTGR 4,4 - JZ memset_end - LGR 0,2 # save pointer to memory area - LGR 1,3 # move pad byte to R1 - LGR 3,4 - SGR 4,4 # no source for MVCLE, only a pad byte - SGR 5,5 - MVCLE 2,4,0(1) # thats it, MVCLE is your friend - JO .-4 - LGR 2,0 # return pointer to mem. -memset_end: - BR 14 - - diff -urN linux-2.6.7-rc3/arch/s390/lib/strcmp.S linux-2.6.7/arch/s390/lib/strcmp.S --- linux-2.6.7-rc3/arch/s390/lib/strcmp.S 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strcmp.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,27 +0,0 @@ -/* - * arch/s390/lib/strcmp.S - * S390 strcmp routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of compare string - * R3 = address of test string - */ - .globl strcmp -strcmp: - SR 0,0 - SR 1,1 - CLST 2,3 - JO .-4 - JE strcmp_equal - IC 0,0(3) - IC 1,0(2) - SR 1,0 -strcmp_equal: - LR 2,1 - BR 14 - diff -urN linux-2.6.7-rc3/arch/s390/lib/strcmp64.S linux-2.6.7/arch/s390/lib/strcmp64.S --- linux-2.6.7-rc3/arch/s390/lib/strcmp64.S 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strcmp64.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,27 +0,0 @@ -/* - * arch/s390/lib/strcmp.S - * S390 strcmp routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of compare string - * R3 = address of test string - */ - .globl strcmp -strcmp: - SGR 0,0 - SGR 1,1 - CLST 2,3 - JO .-4 - JE strcmp_equal - IC 0,0(3) - IC 1,0(2) - SGR 1,0 -strcmp_equal: - LGR 2,1 - BR 14 - diff -urN linux-2.6.7-rc3/arch/s390/lib/strcpy.S linux-2.6.7/arch/s390/lib/strcpy.S --- linux-2.6.7-rc3/arch/s390/lib/strcpy.S 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strcpy.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,20 +0,0 @@ -/* - * arch/s390/kernel/strcpy.S - * S390 strcpy routine - * - * S390 version - * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of destination - * R3 = address of source string - */ - .globl strcpy -strcpy: - sr %r0,%r0 -0: mvst %r2,%r3 - jo 0b - br %r14 - diff -urN linux-2.6.7-rc3/arch/s390/lib/strcpy64.S linux-2.6.7/arch/s390/lib/strcpy64.S --- linux-2.6.7-rc3/arch/s390/lib/strcpy64.S 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strcpy64.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,20 +0,0 @@ -/* - * arch/s390/kernel/strcpy.S - * S390 strcpy routine - * - * S390 version - * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of destination - * R3 = address of source string - */ - .globl strcpy -strcpy: - sgr %r0,%r0 -0: mvst %r2,%r3 - jo 0b - br %r14 - diff -urN linux-2.6.7-rc3/arch/s390/lib/string.c linux-2.6.7/arch/s390/lib/string.c --- linux-2.6.7-rc3/arch/s390/lib/string.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/arch/s390/lib/string.c 2004-06-15 23:10:24.138880144 -0700 @@ -0,0 +1,405 @@ +/* + * arch/s390/lib/string.c + * Optimized string functions + * + * S390 version + * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) + */ + +#define IN_ARCH_STRING_C 1 + +#include +#include + +/* + * Helper functions to find the end of a string + */ +static inline char *__strend(const char *s) +{ + register unsigned long r0 asm("0") = 0; + + asm volatile ("0: srst %0,%1\n" + " jo 0b" + : "+d" (r0), "+a" (s) : : "cc" ); + return (char *) r0; +} + +static inline char *__strnend(const char *s, size_t n) +{ + register unsigned long r0 asm("0") = 0; + const char *p = s + n; + + asm volatile ("0: srst %0,%1\n" + " jo 0b" + : "+d" (p), "+a" (s) : "d" (r0) : "cc" ); + return (char *) p; +} + +/** + * strlen - Find the length of a string + * @s: The string to be sized + * + * returns the length of @s + */ +size_t strlen(const char *s) +{ + return __strend(s) - s; +} +EXPORT_SYMBOL_NOVERS(strlen); + +/** + * strnlen - Find the length of a length-limited string + * @s: The string to be sized + * @n: The maximum number of bytes to search + * + * returns the minimum of the length of @s and @n + */ +size_t strnlen(const char * s, size_t n) +{ + return __strnend(s, n) - s; +} +EXPORT_SYMBOL_NOVERS(strnlen); + +/** + * strcpy - Copy a %NUL terminated string + * @dest: Where to copy the string to + * @src: Where to copy the string from + * + * returns a pointer to @dest + */ +char *strcpy(char *dest, const char *src) +{ + register int r0 asm("0") = 0; + char *ret = dest; + + asm volatile ("0: mvst %0,%1\n" + " jo 0b" + : "+&a" (dest), "+&a" (src) : "d" (r0) + : "cc", "memory" ); + return ret; +} +EXPORT_SYMBOL_NOVERS(strcpy); + +/** + * strlcpy - Copy a %NUL terminated string into a sized buffer + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @size: size of destination buffer + * + * Compatible with *BSD: the result is always a valid + * NUL-terminated string that fits in the buffer (unless, + * of course, the buffer size is zero). It does not pad + * out the result like strncpy() does. + */ +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = __strend(src) - src; + + if (size) { + size_t len = (ret >= size) ? size-1 : ret; + dest[len] = '\0'; + __builtin_memcpy(dest, src, len); + } + return ret; +} +EXPORT_SYMBOL_NOVERS(strlcpy); + +/** + * strncpy - Copy a length-limited, %NUL-terminated string + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @n: The maximum number of bytes to copy + * + * The result is not %NUL-terminated if the source exceeds + * @n bytes. + */ +char *strncpy(char *dest, const char *src, size_t n) +{ + size_t len = __strnend(src, n) - src; + __builtin_memset(dest + len, 0, n - len); + __builtin_memcpy(dest, src, len); + return dest; +} +EXPORT_SYMBOL_NOVERS(strncpy); + +/** + * strcat - Append one %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * + * returns a pointer to @dest + */ +char *strcat(char *dest, const char *src) +{ + register int r0 asm("0") = 0; + unsigned long dummy; + char *ret = dest; + + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + "1: mvst %0,%2\n" + " jo 1b" + : "=&a" (dummy), "+a" (dest), "+a" (src) + : "d" (r0), "0" (0UL) : "cc", "memory" ); + return ret; +} +EXPORT_SYMBOL_NOVERS(strcat); + +/** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @n: The size of the destination buffer. + */ +size_t strlcat(char *dest, const char *src, size_t n) +{ + size_t dsize = __strend(dest) - dest; + size_t len = __strend(src) - src; + size_t res = dsize + len; + + if (dsize < n) { + dest += dsize; + n -= dsize; + if (len >= n) + len = n - 1; + dest[len] = '\0'; + __builtin_memcpy(dest, src, len); + } + return res; +} +EXPORT_SYMBOL_NOVERS(strlcat); + +/** + * strncat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @n: The maximum numbers of bytes to copy + * + * returns a pointer to @dest + * + * Note that in contrast to strncpy, strncat ensures the result is + * terminated. + */ +char *strncat(char *dest, const char *src, size_t n) +{ + size_t len = __strnend(src, n) - src; + char *p = __strend(dest); + + p[len] = '\0'; + __builtin_memcpy(p, src, len); + return dest; +} +EXPORT_SYMBOL_NOVERS(strncat); + +/** + * strcmp - Compare two strings + * @cs: One string + * @ct: Another string + * + * returns 0 if @cs and @ct are equal, + * < 0 if @cs is less than @ct + * > 0 if @cs is greater than @ct + */ +int strcmp(const char *cs, const char *ct) +{ + register int r0 asm("0") = 0; + int ret = 0; + + asm volatile ("0: clst %2,%3\n" + " jo 0b\n" + " je 1f\n" + " ic %0,0(%2)\n" + " ic %1,0(%3)\n" + " sr %0,%1\n" + "1:" + : "+d" (ret), "+d" (r0), "+a" (cs), "+a" (ct) + : : "cc" ); + return ret; +} +EXPORT_SYMBOL_NOVERS(strcmp); + +/** + * strrchr - Find the last occurrence of a character in a string + * @s: The string to be searched + * @c: The character to search for + */ +char * strrchr(const char * s, int c) +{ + size_t len = __strend(s) - s; + + if (len) + do { + if (s[len] == (char) c) + return (char *) s + len; + } while (--len > 0); + return 0; +} +EXPORT_SYMBOL_NOVERS(strrchr); + +/** + * strstr - Find the first substring in a %NUL terminated string + * @s1: The string to be searched + * @s2: The string to search for + */ +char * strstr(const char * s1,const char * s2) +{ + int l1, l2; + + l2 = __strend(s2) - s2; + if (!l2) + return (char *) s1; + l1 = __strend(s1) - s1; + while (l1-- >= l2) { + register unsigned long r2 asm("2") = (unsigned long) s1; + register unsigned long r3 asm("3") = (unsigned long) l2; + register unsigned long r4 asm("4") = (unsigned long) s2; + register unsigned long r5 asm("5") = (unsigned long) l2; + int cc; + + asm volatile ("0: clcle %1,%3,0\n" + " jo 0b\n" + " ipm %0\n" + " srl %0,28" + : "=&d" (cc), "+a" (r2), "+a" (r3), + "+a" (r4), "+a" (r5) : : "cc" ); + if (!cc) + return (char *) s1; + s1++; + } + return 0; +} +EXPORT_SYMBOL_NOVERS(strstr); + +/** + * memchr - Find a character in an area of memory. + * @s: The memory area + * @c: The byte to search for + * @n: The size of the area. + * + * returns the address of the first occurrence of @c, or %NULL + * if @c is not found + */ +void *memchr(const void *s, int c, size_t n) +{ + register int r0 asm("0") = (char) c; + const void *ret = s + n; + + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + " jl 1f\n" + " la %0,0\n" + "1:" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + return (void *) ret; +} +EXPORT_SYMBOL_NOVERS(memchr); + +/** + * memcmp - Compare two areas of memory + * @cs: One area of memory + * @ct: Another area of memory + * @count: The size of the area. + */ +int memcmp(const void *cs, const void *ct, size_t n) +{ + register unsigned long r2 asm("2") = (unsigned long) cs; + register unsigned long r3 asm("3") = (unsigned long) n; + register unsigned long r4 asm("4") = (unsigned long) ct; + register unsigned long r5 asm("5") = (unsigned long) n; + int ret; + + asm volatile ("0: clcle %1,%3,0\n" + " jo 0b\n" + " ipm %0\n" + " srl %0,28" + : "=&d" (ret), "+a" (r2), "+a" (r3), "+a" (r4), "+a" (r5) + : : "cc" ); + if (ret) + ret = *(char *) r2 - *(char *) r4; + return ret; +} +EXPORT_SYMBOL_NOVERS(memcmp); + +/** + * memscan - Find a character in an area of memory. + * @s: The memory area + * @c: The byte to search for + * @n: The size of the area. + * + * returns the address of the first occurrence of @c, or 1 byte past + * the area if @c is not found + */ +void *memscan(void *s, int c, size_t n) +{ + register int r0 asm("0") = (char) c; + const void *ret = s + n; + + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + return (void *) ret; +} +EXPORT_SYMBOL_NOVERS(memscan); + +/** + * memcpy - Copy one area of memory to another + * @dest: Where to copy to + * @src: Where to copy from + * @n: The size of the area. + * + * returns a pointer to @dest + */ +void *memcpy(void *dest, const void *src, size_t n) +{ + return __builtin_memcpy(dest, src, n); +} +EXPORT_SYMBOL_NOVERS(memcpy); + +/** + * bcopy - Copy one area of memory to another + * @src: Where to copy from + * @dest: Where to copy to + * @n: The size of the area. + * + * Note that this is the same as memcpy(), with the arguments reversed. + * memcpy() is the standard, bcopy() is a legacy BSD function. + */ +void bcopy(const void *srcp, void *destp, size_t n) +{ + __builtin_memcpy(destp, srcp, n); +} +EXPORT_SYMBOL_NOVERS(bcopy); + +/** + * memset - Fill a region of memory with the given value + * @s: Pointer to the start of the area. + * @c: The byte to fill the area with + * @n: The size of the area. + * + * returns a pointer to @s + */ +void *memset(void *s, int c, size_t n) +{ + char *xs; + + if (c == 0) + return __builtin_memset(s, 0, n); + + xs = (char *) s; + if (n > 0) + do { + *xs++ = c; + } while (--n > 0); + return s; +} +EXPORT_SYMBOL_NOVERS(memset); + +/* + * missing exports for string functions defined in lib/string.c + */ +EXPORT_SYMBOL_NOVERS(memmove); +EXPORT_SYMBOL_NOVERS(strchr); +EXPORT_SYMBOL_NOVERS(strnchr); +EXPORT_SYMBOL_NOVERS(strncmp); +EXPORT_SYMBOL_NOVERS(strpbrk); diff -urN linux-2.6.7-rc3/arch/s390/lib/strncpy.S linux-2.6.7/arch/s390/lib/strncpy.S --- linux-2.6.7-rc3/arch/s390/lib/strncpy.S 2004-05-09 19:32:52.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strncpy.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,35 +0,0 @@ -/* - * arch/s390/kernel/strncpy.S - * S390 strncpy routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of destination - * R3 = address of source string - * R4 = max number of bytes to copy - */ - .globl strncpy -strncpy: - LR 1,2 # don't touch address in R2 - LTR 4,4 - JZ strncpy_exit # 0 bytes -> nothing to do - SR 0,0 -strncpy_loop: - ICM 0,1,0(3) # ICM sets the cc, IC does not - LA 3,1(3) - STC 0,0(1) - LA 1,1(1) - JZ strncpy_pad # ICM inserted a 0x00 - BRCT 4,strncpy_loop # R4 -= 1, jump to strncpy_loop if > 0 -strncpy_exit: - BR 14 -strncpy_clear: - STC 0,0(1) - LA 1,1(1) -strncpy_pad: - BRCT 4,strncpy_clear - BR 14 diff -urN linux-2.6.7-rc3/arch/s390/lib/strncpy64.S linux-2.6.7/arch/s390/lib/strncpy64.S --- linux-2.6.7-rc3/arch/s390/lib/strncpy64.S 2004-05-09 19:32:02.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/strncpy64.S 1969-12-31 16:00:00.000000000 -0800 @@ -1,35 +0,0 @@ -/* - * arch/s390/kernel/strncpy.S - * S390 strncpy routine - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -/* - * R2 = address of destination - * R3 = address of source string - * R4 = max number of bytes to copy - */ - .globl strncpy -strncpy: - LGR 1,2 # don't touch address in R2 - LTR 4,4 - JZ strncpy_exit # 0 bytes -> nothing to do - SGR 0,0 -strncpy_loop: - ICM 0,1,0(3) # ICM sets the cc, IC does not - LA 3,1(3) - STC 0,0(1) - LA 1,1(1) - JZ strncpy_pad # ICM inserted a 0x00 - BRCTG 4,strncpy_loop # R4 -= 1, jump to strncpy_loop if > 0 -strncpy_exit: - BR 14 -strncpy_clear: - STC 0,0(1) - LA 1,1(1) -strncpy_pad: - BRCTG 4,strncpy_clear - BR 14 diff -urN linux-2.6.7-rc3/arch/s390/lib/uaccess.S linux-2.6.7/arch/s390/lib/uaccess.S --- linux-2.6.7-rc3/arch/s390/lib/uaccess.S 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/uaccess.S 2004-06-15 23:10:24.141880270 -0700 @@ -154,46 +154,57 @@ .align 4 .text .globl __strncpy_from_user_asm - # %r2 = dst, %r3 = src, %r4 = count + # %r2 = count, %r3 = dst, %r4 = src __strncpy_from_user_asm: lhi %r0,0 - lhi %r1,1 - lhi %r5,0 -0: mvcp 0(%r1,%r2),0(%r3),%r0 - tm 0(%r2),0xff - jz 1f - la %r2,1(%r2) - la %r3,1(%r3) - ahi %r5,1 - clr %r5,%r4 - jl 0b -1: lr %r2,%r5 + lr %r1,%r4 + la %r4,0(%r4) # clear high order bit from %r4 + la %r2,0(%r2,%r4) # %r2 points to first byte after string + sacf 256 +0: srst %r2,%r1 + jo 0b + sacf 0 + lr %r1,%r2 + jh 1f # \0 found in string ? + ahi %r1,1 # include \0 in copy +1: slr %r1,%r4 # %r1 = copy length (without \0) + slr %r2,%r4 # %r2 = return length (including \0) +2: mvcp 0(%r1,%r3),0(%r4),%r0 + jnz 3f br %r14 -2: lhi %r2,-EFAULT +3: la %r3,256(%r3) + la %r4,256(%r4) + ahi %r1,-256 + mvcp 0(%r1,%r3),0(%r4),%r0 + jnz 3b br %r14 - .section __ex_table,"a" - .long 0b,2b +4: sacf 0 + lhi %r2,-EFAULT + br %r14 + .section __ex_table,"a" + .long 0b,4b .previous .align 4 .text .globl __strnlen_user_asm - # %r2 = src, %r3 = count + # %r2 = count, %r3 = src __strnlen_user_asm: lhi %r0,0 - lhi %r1,1 - lhi %r5,0 -0: mvcp 24(%r1,%r15),0(%r2),%r0 - ahi %r5,1 - tm 24(%r15),0xff - jz 1f - la %r2,1(%r2) - clr %r5,%r3 - jl 0b -1: lr %r2,%r5 + lr %r1,%r3 + la %r3,0(%r3) # clear high order bit from %r4 + la %r2,0(%r2,%r3) # %r2 points to first byte after string + sacf 256 +0: srst %r2,%r1 + jo 0b + sacf 0 + jh 1f # \0 found in string ? + ahi %r2,1 # strnlen_user result includes the \0 +1: slr %r2,%r3 br %r14 -2: lhi %r2,-EFAULT +2: sacf 0 + lhi %r2,-EFAULT br %r14 - .section __ex_table,"a" + .section __ex_table,"a" .long 0b,2b .previous diff -urN linux-2.6.7-rc3/arch/s390/lib/uaccess64.S linux-2.6.7/arch/s390/lib/uaccess64.S --- linux-2.6.7-rc3/arch/s390/lib/uaccess64.S 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/arch/s390/lib/uaccess64.S 2004-06-15 23:10:24.142880312 -0700 @@ -152,46 +152,55 @@ .align 4 .text .globl __strncpy_from_user_asm - # %r2 = dst, %r3 = src, %r4 = count + # %r2 = count, %r3 = dst, %r4 = src __strncpy_from_user_asm: lghi %r0,0 - lghi %r1,1 - lghi %r5,0 -0: mvcp 0(%r1,%r2),0(%r3),%r0 - tm 0(%r2),0xff - jz 1f - la %r2,1(%r2) - la %r3,1(%r3) - aghi %r5,1 - clgr %r5,%r4 - jl 0b -1: lgr %r2,%r5 + lgr %r1,%r4 + la %r2,0(%r2,%r4) # %r2 points to first byte after string + sacf 256 +0: srst %r2,%r1 + jo 0b + sacf 0 + lgr %r1,%r2 + jh 1f # \0 found in string ? + aghi %r1,1 # include \0 in copy +1: slgr %r1,%r4 # %r1 = copy length (without \0) + slgr %r2,%r4 # %r2 = return length (including \0) +2: mvcp 0(%r1,%r3),0(%r4),%r0 + jnz 3f br %r14 -2: lghi %r2,-EFAULT +3: la %r3,256(%r3) + la %r4,256(%r4) + aghi %r1,-256 + mvcp 0(%r1,%r3),0(%r4),%r0 + jnz 3b br %r14 - .section __ex_table,"a" - .quad 0b,2b +4: sacf 0 + lghi %r2,-EFAULT + br %r14 + .section __ex_table,"a" + .quad 0b,4b .previous .align 4 .text .globl __strnlen_user_asm - # %r2 = src, %r3 = count + # %r2 = count, %r3 = src __strnlen_user_asm: lghi %r0,0 - lghi %r1,1 - lghi %r5,0 -0: mvcp 24(%r1,%r15),0(%r2),%r0 - aghi %r5,1 - tm 24(%r15),0xff - jz 1f - la %r2,1(%r2) - clgr %r5,%r3 - jl 0b -1: lgr %r2,%r5 + lgr %r1,%r3 + la %r2,0(%r2,%r3) # %r2 points to first byte after string + sacf 256 +0: srst %r2,%r1 + jo 0b + sacf 0 + jh 1f # \0 found in string ? + aghi %r2,1 # strnlen_user result includes the \0 +1: slgr %r2,%r3 br %r14 -2: lghi %r2,-EFAULT +2: sacf 0 + lghi %r2,-EFAULT br %r14 - .section __ex_table,"a" + .section __ex_table,"a" .quad 0b,2b .previous diff -urN linux-2.6.7-rc3/arch/s390/mm/extmem.c linux-2.6.7/arch/s390/mm/extmem.c --- linux-2.6.7-rc3/arch/s390/mm/extmem.c 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/arch/s390/mm/extmem.c 2004-06-15 23:10:24.142880312 -0700 @@ -55,7 +55,9 @@ static spinlock_t dcss_lock = SPIN_LOCK_UNLOCKED; static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); -extern struct {unsigned long addr, size, type;} memory_chunk[16]; +extern struct { + unsigned long addr, size, type; +} memory_chunk[MEMORY_CHUNKS]; /* * Create the 8 bytes, ebcdic VM segment name from @@ -258,16 +260,16 @@ shared segment */ dcss_diag_query(dcss_name, &rwattr, &shattr, &segstart, &segend); /* does segment collide with main memory? */ - for (i=0; i<16; i++) { - if (memory_chunk[i].type != 0) - continue; - if (memory_chunk[i].addr > segend) - continue; - if (memory_chunk[i].addr + memory_chunk[i].size <= segstart) - continue; - spin_unlock(&dcss_lock); - return -ENOENT; - } + for (i=0; i < MEMORY_CHUNKS; i++) { + if (memory_chunk[i].type != 0) + continue; + if (memory_chunk[i].addr > segend) + continue; + if (memory_chunk[i].addr + memory_chunk[i].size <= segstart) + continue; + spin_unlock(&dcss_lock); + return -ENOENT; + } /* or does it collide with other (loaded) segments? */ list_for_each(l, &dcss_list) { tmp = list_entry(l, struct dcss_segment, list); diff -urN linux-2.6.7-rc3/arch/s390/mm/ioremap.c linux-2.6.7/arch/s390/mm/ioremap.c --- linux-2.6.7-rc3/arch/s390/mm/ioremap.c 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/arch/s390/mm/ioremap.c 2004-06-15 23:10:24.143880354 -0700 @@ -134,5 +134,5 @@ void iounmap(void *addr) { if (addr > high_memory) - return vfree(addr); + vfree(addr); } diff -urN linux-2.6.7-rc3/arch/sparc/kernel/init_task.c linux-2.6.7/arch/sparc/kernel/init_task.c --- linux-2.6.7-rc3/arch/sparc/kernel/init_task.c 2004-05-09 19:32:39.000000000 -0700 +++ linux-2.6.7/arch/sparc/kernel/init_task.c 2004-06-15 23:10:24.145880438 -0700 @@ -22,6 +22,6 @@ * in etrap.S which assumes it. */ union thread_union init_thread_union - __attribute__((section (".text"))) + __attribute__((section (".text,#alloc"))) __attribute__((aligned (THREAD_SIZE))) = { INIT_THREAD_INFO(init_task) }; diff -urN linux-2.6.7-rc3/arch/sparc/kernel/unaligned.c linux-2.6.7/arch/sparc/kernel/unaligned.c --- linux-2.6.7-rc3/arch/sparc/kernel/unaligned.c 2004-06-15 23:10:00.531886414 -0700 +++ linux-2.6.7/arch/sparc/kernel/unaligned.c 2004-06-15 23:10:24.152880733 -0700 @@ -137,8 +137,8 @@ return &win->locals[reg - 16]; } -static inline unsigned long compute_effective_address(struct pt_regs *regs, - unsigned int insn) +static unsigned long compute_effective_address(struct pt_regs *regs, + unsigned int insn) { unsigned int rs1 = (insn >> 14) & 0x1f; unsigned int rs2 = insn & 0x1f; @@ -153,8 +153,8 @@ } } -static inline unsigned long safe_compute_effective_address(struct pt_regs *regs, - unsigned int insn) +unsigned long safe_compute_effective_address(struct pt_regs *regs, + unsigned int insn) { unsigned int rs1 = (insn >> 14) & 0x1f; unsigned int rs2 = insn & 0x1f; diff -urN linux-2.6.7-rc3/arch/sparc/mm/fault.c linux-2.6.7/arch/sparc/mm/fault.c --- linux-2.6.7-rc3/arch/sparc/mm/fault.c 2004-06-15 23:10:00.533886498 -0700 +++ linux-2.6.7/arch/sparc/mm/fault.c 2004-06-15 23:10:24.153880775 -0700 @@ -201,6 +201,25 @@ return 0; } +extern unsigned long safe_compute_effective_address(struct pt_regs *, + unsigned int); + +static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) +{ + unsigned int insn; + + if (text_fault) + return regs->pc; + + if (regs->psr & PSR_PS) { + insn = *(unsigned int *) regs->pc; + } else { + __get_user(insn, (unsigned int *) regs->pc); + } + + return safe_compute_effective_address(regs, insn); +} + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long address) { @@ -307,7 +326,7 @@ info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ - info.si_addr = (void *)address; + info.si_addr = (void *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); return; @@ -361,7 +380,7 @@ info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; + info.si_addr = (void *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); if (!from_user) @@ -530,7 +549,7 @@ info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ - info.si_addr = (void *)address; + info.si_addr = (void *) address; info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); return; @@ -540,7 +559,7 @@ info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; - info.si_addr = (void *)address; + info.si_addr = (void *) address; info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); } diff -urN linux-2.6.7-rc3/arch/sparc/mm/srmmu.c linux-2.6.7/arch/sparc/mm/srmmu.c --- linux-2.6.7-rc3/arch/sparc/mm/srmmu.c 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/arch/sparc/mm/srmmu.c 2004-06-15 23:10:24.156880902 -0700 @@ -174,7 +174,7 @@ static inline void srmmu_pmd_clear(pmd_t *pmdp) { int i; - for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) + for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) srmmu_set_pte((pte_t *)&pmdp->pmdv[i], __pte(0)); } @@ -234,9 +234,9 @@ int i; ptp = __nocache_pa((unsigned long) ptep) >> 4; - for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) { + for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); - ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4); + ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } @@ -246,9 +246,9 @@ int i; ptp = page_to_pfn(ptep) << (PAGE_SHIFT-4); /* watch for overflow */ - for (i = 0; i < SRMMU_PTRS_PER_PTE_SOFT/SRMMU_PTRS_PER_PTE; i++) { + for (i = 0; i < PTRS_PER_PTE/SRMMU_REAL_PTRS_PER_PTE; i++) { srmmu_set_pte((pte_t *)&pmdp->pmdv[i], SRMMU_ET_PTD | ptp); - ptp += (SRMMU_PTRS_PER_PTE*sizeof(pte_t) >> 4); + ptp += (SRMMU_REAL_PTRS_PER_PTE*sizeof(pte_t) >> 4); } } @@ -263,7 +263,7 @@ static inline pmd_t *srmmu_pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) srmmu_pgd_page(*dir) + - ((address >> SRMMU_PMD_SHIFT_SOFT) & (SRMMU_PTRS_PER_PMD_SOFT - 1)); + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); } /* Find an entry in the third-level page table.. */ @@ -273,7 +273,7 @@ pte = __nocache_va((dir->pmdv[0] & SRMMU_PTD_PMASK) << 4); return (pte_t *) pte + - ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE_SOFT - 1)); + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } static unsigned long srmmu_swp_type(swp_entry_t entry) @@ -487,7 +487,7 @@ static pte_t * srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - return (pte_t *)srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, SRMMU_PTE_SZ_SOFT); + return (pte_t *)srmmu_get_nocache(PTE_SIZE, PTE_SIZE); } static struct page * @@ -502,7 +502,7 @@ static void srmmu_free_pte_fast(pte_t *pte) { - srmmu_free_nocache((unsigned long)pte, SRMMU_PTE_SZ_SOFT); + srmmu_free_nocache((unsigned long)pte, PTE_SIZE); } static void srmmu_pte_free(struct page *pte) @@ -514,7 +514,7 @@ BUG(); p = page_to_pfn(pte) << PAGE_SHIFT; /* Physical address */ p = (unsigned long) __nocache_va(p); /* Nocached virtual */ - srmmu_free_nocache(p, SRMMU_PTE_SZ_SOFT); + srmmu_free_nocache(p, PTE_SIZE); } /* @@ -829,7 +829,7 @@ a = 0x20; b = 0x40; c = 0x60; d = 0x80; e = 0xa0; f = 0xc0; g = 0xe0; - start &= SRMMU_PMD_MASK; + start &= SRMMU_REAL_PMD_MASK; while(start < end) { faddr = (start + (0x10000 - 0x100)); goto inside; @@ -849,7 +849,7 @@ "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f), "r" (g)); } while (faddr != start); - start += SRMMU_PMD_SIZE; + start += SRMMU_REAL_PMD_SIZE; } srmmu_set_context(octx); local_irq_restore(flags); @@ -1067,16 +1067,15 @@ } pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { - ptep = (pte_t *)__srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, - SRMMU_PTE_SZ_SOFT); + ptep = (pte_t *)__srmmu_get_nocache(PTE_SIZE, PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); - memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT); + memset(__nocache_fix(ptep), 0, PTE_SIZE); srmmu_pmd_set(__nocache_fix(pmdp), ptep); } - if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT)) + if (start > (0xffffffffUL - PMD_SIZE)) break; - start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT; + start = (start + PMD_SIZE) & PMD_MASK; } } @@ -1097,16 +1096,16 @@ } pmdp = srmmu_pmd_offset(pgdp, start); if(srmmu_pmd_none(*pmdp)) { - ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, - SRMMU_PTE_SZ_SOFT); + ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, + PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); - memset(ptep, 0, SRMMU_PTE_SZ_SOFT); + memset(ptep, 0, PTE_SIZE); srmmu_pmd_set(pmdp, ptep); } - if (start > (0xffffffffUL - SRMMU_PMD_SIZE_SOFT)) + if (start > (0xffffffffUL - PMD_SIZE)) break; - start = (start + SRMMU_PMD_SIZE_SOFT) & SRMMU_PMD_MASK_SOFT; + start = (start + PMD_SIZE) & PMD_MASK; } } @@ -1136,8 +1135,8 @@ /* A red snapper, see what it really is. */ what = 0; - if(!(start & ~(SRMMU_PMD_MASK))) { - if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_PMD_SIZE) == prompte) + if(!(start & ~(SRMMU_REAL_PMD_MASK))) { + if(srmmu_hwprobe((start-PAGE_SIZE) + SRMMU_REAL_PMD_SIZE) == prompte) what = 1; } @@ -1162,11 +1161,11 @@ } pmdp = srmmu_pmd_offset(__nocache_fix(pgdp), start); if(srmmu_pmd_none(*(pmd_t *)__nocache_fix(pmdp))) { - ptep = (pte_t *) __srmmu_get_nocache(SRMMU_PTE_SZ_SOFT, - SRMMU_PTE_SZ_SOFT); + ptep = (pte_t *) __srmmu_get_nocache(PTE_SIZE, + PTE_SIZE); if (ptep == NULL) early_pgtable_allocfail("pte"); - memset(__nocache_fix(ptep), 0, SRMMU_PTE_SZ_SOFT); + memset(__nocache_fix(ptep), 0, PTE_SIZE); srmmu_pmd_set(__nocache_fix(pmdp), ptep); } if(what == 1) { @@ -1176,9 +1175,9 @@ * good hardware PTE piece. Alternatives seem worse. */ unsigned int x; /* Index of HW PMD in soft cluster */ - x = (start >> SRMMU_PMD_SHIFT) & 15; + x = (start >> PMD_SHIFT) & 15; *(unsigned long *)__nocache_fix(&pmdp->pmdv[x]) = prompte; - start += SRMMU_PMD_SIZE; + start += SRMMU_REAL_PMD_SIZE; continue; } ptep = srmmu_pte_offset(__nocache_fix(pmdp), start); @@ -2139,16 +2138,11 @@ extern void ld_mmu_iounit(void); extern void ___xchg32_sun4md(void); - BTFIXUPSET_SIMM13(pmd_shift, SRMMU_PMD_SHIFT_SOFT); - BTFIXUPSET_SETHI(pmd_size, SRMMU_PMD_SIZE_SOFT); - BTFIXUPSET_SETHI(pmd_mask, SRMMU_PMD_MASK_SOFT); - BTFIXUPSET_SIMM13(pgdir_shift, SRMMU_PGDIR_SHIFT); BTFIXUPSET_SETHI(pgdir_size, SRMMU_PGDIR_SIZE); BTFIXUPSET_SETHI(pgdir_mask, SRMMU_PGDIR_MASK); - BTFIXUPSET_SIMM13(ptrs_per_pte, SRMMU_PTRS_PER_PTE_SOFT); - BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD_SOFT); + BTFIXUPSET_SIMM13(ptrs_per_pmd, SRMMU_PTRS_PER_PMD); BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD); BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE)); diff -urN linux-2.6.7-rc3/arch/sparc/mm/sun4c.c linux-2.6.7/arch/sparc/mm/sun4c.c --- linux-2.6.7-rc3/arch/sparc/mm/sun4c.c 2004-05-09 19:33:06.000000000 -0700 +++ linux-2.6.7/arch/sparc/mm/sun4c.c 2004-06-15 23:10:24.157880944 -0700 @@ -2137,14 +2137,10 @@ printk("Loading sun4c MMU routines\n"); /* First the constants */ - BTFIXUPSET_SIMM13(pmd_shift, SUN4C_PMD_SHIFT); - BTFIXUPSET_SETHI(pmd_size, SUN4C_PMD_SIZE); - BTFIXUPSET_SETHI(pmd_mask, SUN4C_PMD_MASK); BTFIXUPSET_SIMM13(pgdir_shift, SUN4C_PGDIR_SHIFT); BTFIXUPSET_SETHI(pgdir_size, SUN4C_PGDIR_SIZE); BTFIXUPSET_SETHI(pgdir_mask, SUN4C_PGDIR_MASK); - BTFIXUPSET_SIMM13(ptrs_per_pte, SUN4C_PTRS_PER_PTE); BTFIXUPSET_SIMM13(ptrs_per_pmd, SUN4C_PTRS_PER_PMD); BTFIXUPSET_SIMM13(ptrs_per_pgd, SUN4C_PTRS_PER_PGD); BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE); diff -urN linux-2.6.7-rc3/arch/sparc64/defconfig linux-2.6.7/arch/sparc64/defconfig --- linux-2.6.7-rc3/arch/sparc64/defconfig 2004-06-15 23:10:00.535886582 -0700 +++ linux-2.6.7/arch/sparc64/defconfig 2004-06-15 23:10:24.159881028 -0700 @@ -233,7 +233,6 @@ # CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDETAPE=m # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -342,7 +341,6 @@ CONFIG_SCSI_SATA_VIA=m CONFIG_SCSI_SATA_VITESSE=m # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set CONFIG_SCSI_DMX3191D=m # CONFIG_SCSI_EATA is not set CONFIG_SCSI_EATA_PIO=m @@ -1587,6 +1585,7 @@ # CONFIG_USB_IBMCAM is not set # CONFIG_USB_KONICAWC is not set # CONFIG_USB_OV511 is not set +CONFIG_USB_PWC=m # CONFIG_USB_SE401 is not set # CONFIG_USB_STV680 is not set CONFIG_USB_W9968CF=m diff -urN linux-2.6.7-rc3/arch/sparc64/kernel/chmc.c linux-2.6.7/arch/sparc64/kernel/chmc.c --- linux-2.6.7-rc3/arch/sparc64/kernel/chmc.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/arch/sparc64/kernel/chmc.c 2004-06-15 23:10:24.160881070 -0700 @@ -243,8 +243,9 @@ static u64 read_mcreg(struct mctrl_info *mp, unsigned long offset) { unsigned long ret; + int this_cpu = get_cpu(); - if (mp->portid == smp_processor_id()) { + if (mp->portid == this_cpu) { __asm__ __volatile__("ldxa [%1] %2, %0" : "=r" (ret) : "r" (offset), "i" (ASI_MCU_CTRL_REG)); @@ -254,6 +255,8 @@ : "r" (mp->regs + offset), "i" (ASI_PHYS_BYPASS_EC_E)); } + put_cpu(); + return ret; } diff -urN linux-2.6.7-rc3/arch/sparc64/kernel/irq.c linux-2.6.7/arch/sparc64/kernel/irq.c --- linux-2.6.7-rc3/arch/sparc64/kernel/irq.c 2004-06-15 23:10:00.540886793 -0700 +++ linux-2.6.7/arch/sparc64/kernel/irq.c 2004-06-15 23:10:24.164881238 -0700 @@ -174,6 +174,8 @@ if (imap == 0UL) return; + preempt_disable(); + if (tlb_type == cheetah || tlb_type == cheetah_plus) { unsigned long ver; @@ -214,6 +216,8 @@ * Things like FFB can now be handled via the new IRQ mechanism. */ upa_writel(tid | IMAP_VALID, imap); + + preempt_enable(); } /* This now gets passed true ino's as well. */ diff -urN linux-2.6.7-rc3/arch/sparc64/kernel/smp.c linux-2.6.7/arch/sparc64/kernel/smp.c --- linux-2.6.7-rc3/arch/sparc64/kernel/smp.c 2004-06-15 23:10:00.550887214 -0700 +++ linux-2.6.7/arch/sparc64/kernel/smp.c 2004-06-15 23:10:24.175881701 -0700 @@ -547,15 +547,18 @@ static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, cpumask_t mask) { u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff)); + int this_cpu = get_cpu(); cpus_and(mask, mask, cpu_online_map); - cpu_clear(smp_processor_id(), mask); + cpu_clear(this_cpu, mask); if (tlb_type == spitfire) spitfire_xcall_deliver(data0, data1, data2, mask); else cheetah_xcall_deliver(data0, data1, data2, mask); /* NOTE: Caller runs local copy on master. */ + + put_cpu(); } extern unsigned long xcall_sync_tick; @@ -685,11 +688,12 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu) { cpumask_t mask = cpumask_of_cpu(cpu); + int this_cpu = get_cpu(); #ifdef CONFIG_DEBUG_DCFLUSH atomic_inc(&dcpage_flushes); #endif - if (cpu == smp_processor_id()) { + if (cpu == this_cpu) { __local_flush_dcache_page(page); } else if (cpu_online(cpu)) { u64 data0; @@ -714,14 +718,17 @@ atomic_inc(&dcpage_flushes_xcall); #endif } + + put_cpu(); } void flush_dcache_page_all(struct mm_struct *mm, struct page *page) { cpumask_t mask = cpu_online_map; u64 data0; + int this_cpu = get_cpu(); - cpu_clear(smp_processor_id(), mask); + cpu_clear(this_cpu, mask); #ifdef CONFIG_DEBUG_DCFLUSH atomic_inc(&dcpage_flushes); @@ -747,6 +754,8 @@ #endif flush_self: __local_flush_dcache_page(page); + + put_cpu(); } void smp_receive_signal(int cpu) @@ -842,7 +851,7 @@ { u32 ctx = CTX_HWBITS(mm->context); - int cpu = smp_processor_id(); + int cpu = get_cpu(); if (atomic_read(&mm->mm_users) == 1) { /* See smp_flush_tlb_page for info about this. */ @@ -856,6 +865,8 @@ local_flush_and_out: __flush_tlb_mm(ctx, SECONDARY_CONTEXT); + + put_cpu(); } } @@ -863,7 +874,7 @@ unsigned long end) { u32 ctx = CTX_HWBITS(mm->context); - int cpu = smp_processor_id(); + int cpu = get_cpu(); start &= PAGE_MASK; end = PAGE_ALIGN(end); @@ -880,6 +891,8 @@ local_flush_and_out: __flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start)); + + put_cpu(); } void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -898,7 +911,7 @@ { { u32 ctx = CTX_HWBITS(mm->context); - int cpu = smp_processor_id(); + int cpu = get_cpu(); page &= PAGE_MASK; if (mm == current->active_mm && @@ -938,6 +951,8 @@ local_flush_and_out: __flush_tlb_page(ctx, page, SECONDARY_CONTEXT); + + put_cpu(); } } diff -urN linux-2.6.7-rc3/arch/sparc64/kernel/sparc64_ksyms.c linux-2.6.7/arch/sparc64/kernel/sparc64_ksyms.c --- linux-2.6.7-rc3/arch/sparc64/kernel/sparc64_ksyms.c 2004-06-15 23:10:00.550887214 -0700 +++ linux-2.6.7/arch/sparc64/kernel/sparc64_ksyms.c 2004-06-15 23:10:24.175881701 -0700 @@ -189,6 +189,11 @@ EXPORT_SYMBOL(___test_and_set_le_bit); EXPORT_SYMBOL(___test_and_clear_le_bit); +/* Bit searching */ +EXPORT_SYMBOL(find_next_bit); +EXPORT_SYMBOL(find_next_zero_bit); +EXPORT_SYMBOL(find_next_zero_le_bit); + EXPORT_SYMBOL(ivector_table); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); diff -urN linux-2.6.7-rc3/arch/sparc64/kernel/unaligned.c linux-2.6.7/arch/sparc64/kernel/unaligned.c --- linux-2.6.7-rc3/arch/sparc64/kernel/unaligned.c 2004-06-15 23:10:00.564887803 -0700 +++ linux-2.6.7/arch/sparc64/kernel/unaligned.c 2004-06-15 23:10:24.189882291 -0700 @@ -158,8 +158,8 @@ } } -static unsigned long compute_effective_address(struct pt_regs *regs, - unsigned int insn, unsigned int rd) +unsigned long compute_effective_address(struct pt_regs *regs, + unsigned int insn, unsigned int rd) { unsigned int rs1 = (insn >> 14) & 0x1f; unsigned int rs2 = insn & 0x1f; diff -urN linux-2.6.7-rc3/arch/sparc64/lib/Makefile linux-2.6.7/arch/sparc64/lib/Makefile --- linux-2.6.7-rc3/arch/sparc64/lib/Makefile 2004-06-15 23:10:00.564887803 -0700 +++ linux-2.6.7/arch/sparc64/lib/Makefile 2004-06-15 23:10:24.189882291 -0700 @@ -10,7 +10,8 @@ VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \ VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o \ U3memcpy.o U3copy_from_user.o U3copy_to_user.o \ - U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o + U3copy_in_user.o mcount.o ipcsum.o rwsem.o xor.o splock.o \ + find_bit.o lib-$(CONFIG_DEBUG_SPINLOCK) += debuglocks.o lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff -urN linux-2.6.7-rc3/arch/sparc64/lib/debuglocks.c linux-2.6.7/arch/sparc64/lib/debuglocks.c --- linux-2.6.7-rc3/arch/sparc64/lib/debuglocks.c 2004-06-15 23:10:00.565887845 -0700 +++ linux-2.6.7/arch/sparc64/lib/debuglocks.c 2004-06-15 23:10:24.190882333 -0700 @@ -55,7 +55,7 @@ { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -80,12 +80,14 @@ lock->owner_cpu = cpu; current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } int _spin_trylock(spinlock_t *lock) { unsigned long val, caller; - int cpu = smp_processor_id(); + int cpu = get_cpu(); GET_CALLER(caller); __asm__ __volatile__("ldstub [%1], %0" @@ -99,6 +101,9 @@ current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); } + + put_cpu(); + return val == 0; } @@ -117,7 +122,7 @@ { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -148,13 +153,15 @@ rw->reader_pc[cpu] = ((unsigned int)caller); current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } void _do_read_unlock (rwlock_t *rw, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -181,13 +188,15 @@ } goto runlock_again; } + + put_cpu(); } void _do_write_lock (rwlock_t *rw, char *str) { unsigned long caller, val; int stuck = INIT_STUCK; - int cpu = smp_processor_id(); + int cpu = get_cpu(); int shown = 0; GET_CALLER(caller); @@ -263,6 +272,8 @@ rw->writer_cpu = cpu; current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + + put_cpu(); } void _do_write_unlock(rwlock_t *rw) @@ -302,7 +313,7 @@ int _do_write_trylock (rwlock_t *rw, char *str) { unsigned long caller, val; - int cpu = smp_processor_id(); + int cpu = get_cpu(); GET_CALLER(caller); @@ -322,8 +333,10 @@ : "0" (&(rw->lock)) : "g3", "g5", "g7", "memory"); - if (val) + if (val) { + put_cpu(); return 0; + } if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) { /* Readers still around, drop the write @@ -342,6 +355,8 @@ : "r" (&(rw->lock)) : "g3", "g5", "g7", "cc", "memory"); + put_cpu(); + return 0; } @@ -351,6 +366,8 @@ current->thread.smp_lock_count++; current->thread.smp_lock_pc = ((unsigned int)caller); + put_cpu(); + return 1; } diff -urN linux-2.6.7-rc3/arch/sparc64/lib/find_bit.c linux-2.6.7/arch/sparc64/lib/find_bit.c --- linux-2.6.7-rc3/arch/sparc64/lib/find_bit.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/arch/sparc64/lib/find_bit.c 2004-06-15 23:10:24.190882333 -0700 @@ -0,0 +1,125 @@ +#include + +/** + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> 6); + unsigned long result = offset & ~63UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 63UL; + if (offset) { + tmp = *(p++); + tmp &= (~0UL << offset); + if (size < 64) + goto found_first; + if (tmp) + goto found_middle; + size -= 64; + result += 64; + } + while (size & ~63UL) { + if ((tmp = *(p++))) + goto found_middle; + result += 64; + size -= 64; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= (~0UL >> (64 - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} + +/* find_next_zero_bit() finds the first zero bit in a bit string of length + * 'size' bits, starting the search at bit 'offset'. This is largely based + * on Linus's ALPHA routines, which are pretty portable BTW. + */ + +unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> 6); + unsigned long result = offset & ~63UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 63UL; + if (offset) { + tmp = *(p++); + tmp |= ~0UL >> (64-offset); + if (size < 64) + goto found_first; + if (~tmp) + goto found_middle; + size -= 64; + result += 64; + } + while (size & ~63UL) { + if (~(tmp = *(p++))) + goto found_middle; + result += 64; + size -= 64; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ffz(tmp); +} + +unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> 6); + unsigned long result = offset & ~63UL; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 63UL; + if(offset) { + tmp = __swab64p(p++); + tmp |= (~0UL >> (64-offset)); + if(size < 64) + goto found_first; + if(~tmp) + goto found_middle; + size -= 64; + result += 64; + } + while(size & ~63) { + if(~(tmp = __swab64p(p++))) + goto found_middle; + result += 64; + size -= 64; + } + if(!size) + return result; + tmp = __swab64p(p); +found_first: + tmp |= (~0UL << size); + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found_middle: + return result + ffz(tmp); +} diff -urN linux-2.6.7-rc3/arch/sparc64/mm/fault.c linux-2.6.7/arch/sparc64/mm/fault.c --- linux-2.6.7-rc3/arch/sparc64/mm/fault.c 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/arch/sparc64/mm/fault.c 2004-06-15 23:10:24.192882417 -0700 @@ -207,14 +207,21 @@ return insn; } -static void do_fault_siginfo(int code, int sig, unsigned long address) +extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); + +static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, + unsigned int insn, int fault_code) { siginfo_t info; info.si_code = code; info.si_signo = sig; info.si_errno = 0; - info.si_addr = (void *) address; + if (fault_code & FAULT_CODE_ITLB) + info.si_addr = (void *) regs->tpc; + else + info.si_addr = (void *) + compute_effective_address(regs, insn, 0); info.si_trapno = 0; force_sig_info(sig, &info, current); } @@ -295,7 +302,7 @@ /* The si_code was set to make clear whether * this was a SEGV_MAPERR or SEGV_ACCERR fault. */ - do_fault_siginfo(si_code, SIGSEGV, address); + do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code); return; } @@ -471,7 +478,7 @@ * Send a sigbus, regardless of whether we were in kernel * or user mode. */ - do_fault_siginfo(BUS_ADRERR, SIGBUS, address); + do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code); /* Kernel mode? Handle exceptions or die */ if (regs->tstate & TSTATE_PRIV) diff -urN linux-2.6.7-rc3/arch/sparc64/mm/init.c linux-2.6.7/arch/sparc64/mm/init.c --- linux-2.6.7-rc3/arch/sparc64/mm/init.c 2004-06-15 23:10:00.567887929 -0700 +++ linux-2.6.7/arch/sparc64/mm/init.c 2004-06-15 23:10:24.193882459 -0700 @@ -152,9 +152,9 @@ #define dcache_dirty_cpu(page) \ (((page)->flags >> 24) & (NR_CPUS - 1UL)) -static __inline__ void set_dcache_dirty(struct page *page) +static __inline__ void set_dcache_dirty(struct page *page, int this_cpu) { - unsigned long mask = smp_processor_id(); + unsigned long mask = this_cpu; unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL); mask = (mask << 24) | (1UL << PG_dcache_dirty); __asm__ __volatile__("1:\n\t" @@ -206,16 +206,19 @@ (page = pfn_to_page(pfn), page_mapping(page)) && ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) { int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL)); + int this_cpu = get_cpu(); /* This is just to optimize away some function calls * in the SMP case. */ - if (cpu == smp_processor_id()) + if (cpu == this_cpu) flush_dcache_page_impl(page); else smp_flush_dcache_page_impl(page, cpu); clear_dcache_dirty_cpu(page, cpu); + + put_cpu(); } if (get_thread_fault_code()) __update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS, @@ -227,14 +230,15 @@ struct address_space *mapping = page_mapping(page); int dirty = test_bit(PG_dcache_dirty, &page->flags); int dirty_cpu = dcache_dirty_cpu(page); + int this_cpu = get_cpu(); if (mapping && !mapping_mapped(mapping)) { if (dirty) { - if (dirty_cpu == smp_processor_id()) - return; + if (dirty_cpu == this_cpu) + goto out; smp_flush_dcache_page_impl(page, dirty_cpu); } - set_dcache_dirty(page); + set_dcache_dirty(page, this_cpu); } else { /* We could delay the flush for the !page_mapping * case too. But that case is for exec env/arg @@ -243,6 +247,9 @@ */ flush_dcache_page_impl(page); } + +out: + put_cpu(); } /* When shared+writable mmaps of files go away, we lose all dirty diff -urN linux-2.6.7-rc3/arch/x86_64/kernel/io_apic.c linux-2.6.7/arch/x86_64/kernel/io_apic.c --- linux-2.6.7-rc3/arch/x86_64/kernel/io_apic.c 2004-06-15 23:10:00.583888603 -0700 +++ linux-2.6.7/arch/x86_64/kernel/io_apic.c 2004-06-15 23:10:24.208883091 -0700 @@ -252,7 +252,8 @@ switch (vendor) { case PCI_VENDOR_ID_VIA: #ifdef CONFIG_GART_IOMMU - if (end_pfn >= (0xffffffff>>PAGE_SHIFT) && + if ((end_pfn >= (0xffffffff>>PAGE_SHIFT) || + force_iommu) && !iommu_aperture_allowed) { printk(KERN_INFO "Looks like a VIA chipset. Disabling IOMMU. Overwrite with \"iommu=allowed\"\n"); diff -urN linux-2.6.7-rc3/arch/x86_64/kernel/mce.c linux-2.6.7/arch/x86_64/kernel/mce.c --- linux-2.6.7-rc3/arch/x86_64/kernel/mce.c 2004-06-15 23:10:00.584888645 -0700 +++ linux-2.6.7/arch/x86_64/kernel/mce.c 2004-06-15 23:10:24.210883175 -0700 @@ -25,7 +25,8 @@ #define NR_BANKS 5 static int mce_disabled __initdata; -/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic */ +/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, + 3: never panic or exit (for testing only) */ static int tolerant = 1; static int banks; static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL }; @@ -105,7 +106,10 @@ } if (backup) print_mce(backup); - panic(msg); + if (tolerant >= 3) + printk("Fake panic: %s\n", msg); + else + panic(msg); } static int mce_available(struct cpuinfo_x86 *c) @@ -151,23 +155,30 @@ if (!bank[i]) continue; - /* Did this bank cause the exception? */ - /* XXX: check more flags */ - if ((m.status & MCI_STATUS_PCC)) { - panicm = m; - } else { - m.rip = 0; - m.cs = 0; - } - m.misc = 0; m.addr = 0; rdmsrl(MSR_IA32_MC0_STATUS + i*4, m.status); if ((m.status & MCI_STATUS_VAL) == 0) continue; + /* Should be implied by the banks check above, but + check it anyways */ + if ((m.status & MCI_STATUS_EN) == 0) + continue; + + /* Did this bank cause the exception? */ + /* Assume that the bank with uncorrectable errors did it, + and that there is only a single one. */ + if (m.status & MCI_STATUS_UC) { + panicm = m; + } else { + m.rip = 0; + m.cs = 0; + } - nowayout |= !!(m.status & (MCI_STATUS_OVER|MCI_STATUS_PCC)); + /* In theory _OVER could be a nowayout too, but + assume any overflowed errors were no fatal. */ + nowayout |= !!(m.status & MCI_STATUS_PCC); kill_it |= !!(m.status & MCI_STATUS_UC); m.bank = i; @@ -206,7 +217,8 @@ /* do_exit takes an awful lot of locks and has as slight risk of deadlocking. If you don't want that don't set tolerant >= 2 */ - do_exit(SIGBUS); + if (tolerant < 3) + do_exit(SIGBUS); } } diff -urN linux-2.6.7-rc3/arch/x86_64/mm/fault.c linux-2.6.7/arch/x86_64/mm/fault.c --- linux-2.6.7-rc3/arch/x86_64/mm/fault.c 2004-06-15 23:10:00.595889108 -0700 +++ linux-2.6.7/arch/x86_64/mm/fault.c 2004-06-15 23:10:24.221883638 -0700 @@ -211,7 +211,8 @@ int unhandled_signal(struct task_struct *tsk, int sig) { /* Warn for strace, but not for gdb */ - if ((tsk->ptrace & (PT_PTRACED|PT_TRACESYSGOOD)) == PT_PTRACED) + if (!test_ti_thread_flag(tsk->thread_info, TIF_SYSCALL_TRACE) && + (tsk->ptrace & PT_PTRACED)) return 0; return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); @@ -374,7 +375,7 @@ (address >> 32)) return; - if (exception_trace && !unhandled_signal(tsk, SIGSEGV)) { + if (exception_trace && unhandled_signal(tsk, SIGSEGV)) { printk(KERN_INFO "%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n", tsk->comm, tsk->pid, address, regs->rip, diff -urN linux-2.6.7-rc3/arch/x86_64/mm/ioremap.c linux-2.6.7/arch/x86_64/mm/ioremap.c --- linux-2.6.7-rc3/arch/x86_64/mm/ioremap.c 2004-06-15 23:10:00.596889150 -0700 +++ linux-2.6.7/arch/x86_64/mm/ioremap.c 2004-06-15 23:10:24.221883638 -0700 @@ -158,6 +158,7 @@ area = get_vm_area(size, VM_IOREMAP); if (!area) return NULL; + area->phys_addr = phys_addr; addr = area->addr; if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { vunmap(addr); diff -urN linux-2.6.7-rc3/crypto/digest.c linux-2.6.7/crypto/digest.c --- linux-2.6.7-rc3/crypto/digest.c 2004-05-09 19:31:58.000000000 -0700 +++ linux-2.6.7/crypto/digest.c 2004-06-15 23:10:24.223883722 -0700 @@ -27,13 +27,28 @@ struct scatterlist *sg, unsigned int nsg) { unsigned int i; - + for (i = 0; i < nsg; i++) { - char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; - tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), - p, sg[i].length); - crypto_kunmap(p, 0); - crypto_yield(tfm); + + struct page *pg = sg[i].page; + unsigned int offset = sg[i].offset; + unsigned int l = sg[i].length; + + do { + unsigned int bytes_from_page = min(l, ((unsigned int) + (PAGE_SIZE)) - + offset); + char *p = crypto_kmap(pg, 0) + offset; + + tfm->__crt_alg->cra_digest.dia_update + (crypto_tfm_ctx(tfm), p, + bytes_from_page); + crypto_kunmap(p, 0); + crypto_yield(tfm); + offset = 0; + pg++; + l -= bytes_from_page; + } while (l > 0); } } diff -urN linux-2.6.7-rc3/drivers/atm/ambassador.c linux-2.6.7/drivers/atm/ambassador.c --- linux-2.6.7-rc3/drivers/atm/ambassador.c 2004-06-15 23:10:00.656891675 -0700 +++ linux-2.6.7/drivers/atm/ambassador.c 2004-06-15 23:10:24.752905994 -0700 @@ -2215,7 +2215,7 @@ } /* amb_reset */ - return -1; + return -EINVAL; } static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev) @@ -2257,27 +2257,31 @@ spin_lock_init (&dev->rxq[pool].lock); } -static void setup_pci_dev(struct pci_dev *pci_dev) +static int setup_pci_dev(struct pci_dev *pci_dev) { - unsigned char lat; + unsigned char lat; + int ret; - /* XXX check return value */ - pci_enable_device(pci_dev); - - // enable bus master accesses - pci_set_master(pci_dev); + // enable bus master accesses + pci_set_master(pci_dev); - // frobnicate latency (upwards, usually) - pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat); - if (pci_lat) { - PRINTD (DBG_INIT, "%s PCI latency timer from %hu to %hu", - "changing", lat, pci_lat); - pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, pci_lat); - } else if (lat < MIN_PCI_LATENCY) { - PRINTK (KERN_INFO, "%s PCI latency timer from %hu to %hu", - "increasing", lat, MIN_PCI_LATENCY); - pci_write_config_byte (pci_dev, PCI_LATENCY_TIMER, MIN_PCI_LATENCY); - } + ret = pci_enable_device(pci_dev); + if (ret < 0) + goto out; + + // frobnicate latency (upwards, usually) + pci_read_config_byte (pci_dev, PCI_LATENCY_TIMER, &lat); + + if (!pci_lat) + pci_lat = (lat < MIN_PCI_LATENCY) ? MIN_PCI_LATENCY : lat; + + if (lat != pci_lat) { + PRINTK (KERN_INFO, "Changing PCI latency timer from %hu to %hu", + lat, pci_lat); + pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, pci_lat); + } +out: + return ret; } static int __init do_pci_device(struct pci_dev *pci_dev) @@ -2294,40 +2298,43 @@ " IO %x, IRQ %u, MEM %p", iobase, irq, membase); // check IO region - if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) { + err = pci_request_region(pci_dev, 1, DEV_LABEL); + if (err < 0) { PRINTK (KERN_ERR, "IO range already in use!"); - return -EBUSY; + goto out; } dev = kmalloc (sizeof(amb_dev), GFP_KERNEL); if (!dev) { PRINTK (KERN_ERR, "out of memory!"); err = -ENOMEM; - goto out; + goto out_release; } setup_dev(dev, pci_dev); - if (amb_init (dev)) { + err = amb_init(dev); + if (err < 0) { PRINTK (KERN_ERR, "adapter initialisation failure"); - err = -EINVAL; - goto out1; + goto out_free; } - setup_pci_dev(pci_dev); + err = setup_pci_dev(pci_dev); + if (err < 0) + goto out_reset; // grab (but share) IRQ and install handler - if (request_irq (irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev)) { + err = request_irq(irq, interrupt_handler, SA_SHIRQ, DEV_LABEL, dev); + if (err < 0) { PRINTK (KERN_ERR, "request IRQ failed!"); - err = -EBUSY; - goto out2; + goto out_disable; } dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); if (!dev->atm_dev) { PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); err = -EINVAL; - goto out3; + goto out_free_irq; } PRINTD (DBG_INFO, "registered Madge ATM adapter (no. %d) (%p) at %p", @@ -2348,17 +2355,20 @@ // enable host interrupts interrupts_on (dev); - return 0; - -out3: - free_irq (irq, dev); -out2: - amb_reset (dev, 0); -out1: - kfree (dev); out: - release_region (iobase, AMB_EXTENT); return err; + +out_free_irq: + free_irq(irq, dev); +out_disable: + pci_disable_device(pci_dev); +out_reset: + amb_reset(dev, 0); +out_free: + kfree(dev); +out_release: + pci_release_region(pci_dev, 1); + goto out; } static int __init amb_probe (void) { @@ -2488,7 +2498,10 @@ del_timer_sync(&housekeeping); while (amb_devs) { + struct pci_dev *pdev; + dev = amb_devs; + pdev = dev->pci_dev; amb_devs = dev->prev; PRINTD (DBG_INFO|DBG_INIT, "closing %p (atm_dev = %p)", dev, dev->atm_dev); @@ -2496,11 +2509,12 @@ drain_rx_pools (dev); interrupts_off (dev); amb_reset (dev, 0); + free_irq (dev->irq, dev); + pci_disable_device (pdev); destroy_queues (dev); atm_dev_deregister (dev->atm_dev); - free_irq (dev->irq, dev); - release_region (dev->iobase, AMB_EXTENT); kfree (dev); + pci_release_region (pdev, 1); } return; diff -urN linux-2.6.7-rc3/drivers/block/paride/epat.c linux-2.6.7/drivers/block/paride/epat.c --- linux-2.6.7-rc3/drivers/block/paride/epat.c 2004-05-09 19:33:22.000000000 -0700 +++ linux-2.6.7/drivers/block/paride/epat.c 2004-06-15 23:10:26.080961906 -0700 @@ -31,6 +31,12 @@ #define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) #define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) +static int epatc8; + +module_param(epatc8, int, 0); +MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, " + "used in any recent Imation SuperDisk (LS-120) drive."); + /* cont = 0 IDE register file cont = 1 IDE control registers cont = 2 internal EPAT registers @@ -209,15 +215,18 @@ { pi->saved_r0 = r0(); pi->saved_r2 = r2(); -#ifdef CONFIG_PARIDE_EPATC8 /* Initialize the chip */ - CPP(0);CPP(0x40);CPP(0xe0); - w0(0);w2(1);w2(4); - WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10); - WR(0xe,0xf);WR(0xf,4); - /* WR(0xe,0xa);WR(0xf,4); */ - WR(0xe,0xd);WR(0xf,0); - /* CPP(0x30); */ + CPP(0); + + if (epatc8) { + CPP(0x40);CPP(0xe0); + w0(0);w2(1);w2(4); + WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10); + WR(0xe,0xf);WR(0xf,4); + /* WR(0xe,0xa);WR(0xf,4); */ + WR(0xe,0xd);WR(0xf,0); + /* CPP(0x30); */ + } /* Connect to the chip */ CPP(0xe0); @@ -227,15 +236,10 @@ /* Request EPP */ w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4); } -#else - CPP(0); CPP(0xe0); - w0(0); w2(1); w2(4); - if (pi->mode >= 3) { - w0(0); w2(1); w2(4); w2(0xc); - w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4); + + if (!epatc8) { + WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10); } - WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10); -#endif } static void epat_disconnect (PIA *pi) @@ -320,6 +324,9 @@ static int __init epat_init(void) { +#ifdef CONFIG_PARIDE_EPATC8 + epatc8 = 1; +#endif return pi_register(&epat)-1; } diff -urN linux-2.6.7-rc3/drivers/block/rd.c linux-2.6.7/drivers/block/rd.c --- linux-2.6.7-rc3/drivers/block/rd.c 2004-06-15 23:10:00.711893991 -0700 +++ linux-2.6.7/drivers/block/rd.c 2004-06-15 23:10:26.434976810 -0700 @@ -108,8 +108,21 @@ struct buffer_head *head = bh; do { - if (!buffer_uptodate(bh)) + if (!buffer_uptodate(bh)) { memset(bh->b_data, 0, bh->b_size); + /* + * akpm: I'm totally undecided about this. The + * buffer has just been magically brought "up to + * date", but nobody should want to be reading + * it anyway, because it hasn't been used for + * anything yet. It is still in a "not read + * from disk yet" state. + * + * But non-uptodate buffers against an uptodate + * page are against the rules. So do it anyway. + */ + set_buffer_uptodate(bh); + } } while ((bh = bh->b_this_page) != head); } else { memset(page_address(page), 0, PAGE_CACHE_SIZE); diff -urN linux-2.6.7-rc3/drivers/cdrom/cdrom.c linux-2.6.7/drivers/cdrom/cdrom.c --- linux-2.6.7-rc3/drivers/cdrom/cdrom.c 2004-06-15 23:10:00.725894580 -0700 +++ linux-2.6.7/drivers/cdrom/cdrom.c 2004-06-15 23:10:26.739989652 -0700 @@ -671,28 +671,24 @@ { struct packet_command cgc; char buffer[16]; - struct feature_header *fh; __u16 *feature_code; int ret; init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); - cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */ - cgc.cmd[3] = CDF_HWDM; /* often 0x0024 */ - cgc.cmd[8] = sizeof(buffer); /* often 0x10 */ + cgc.cmd[0] = GPCMD_GET_CONFIGURATION; + cgc.cmd[3] = CDF_HWDM; + cgc.cmd[8] = sizeof(buffer); cgc.quiet = 1; if ((ret = cdi->ops->generic_packet(cdi, &cgc))) return ret; - fh = (struct feature_header *)&buffer[0]; - ret = 1; - if (be32_to_cpu(fh->data_len) >= (sizeof(struct feature_header)+8)) { - feature_code = (__u16 *)&buffer[sizeof(struct feature_header)]; - if (CDF_HWDM == be16_to_cpu(*feature_code)) - ret = 0; - } - return ret; + feature_code = (__u16 *) &buffer[sizeof(struct feature_header)]; + if (be16_to_cpu(*feature_code) == CDF_HWDM) + return 0; + + return 1; } diff -urN linux-2.6.7-rc3/drivers/char/drm/drm_ioctl.h linux-2.6.7/drivers/char/drm/drm_ioctl.h --- linux-2.6.7-rc3/drivers/char/drm/drm_ioctl.h 2004-06-15 23:10:00.750895632 -0700 +++ linux-2.6.7/drivers/char/drm/drm_ioctl.h 2004-06-15 23:10:27.004000767 -0700 @@ -142,6 +142,13 @@ snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); + dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2, + DRM_MEM_DRIVER); + if (dev->devname == NULL) + return ENOMEM; + + sprintf(dev->devname, "%s@%s", dev->name, dev->unique); + return 0; } diff -urN linux-2.6.7-rc3/drivers/char/drm/gamma_dma.c linux-2.6.7/drivers/char/drm/gamma_dma.c --- linux-2.6.7-rc3/drivers/char/drm/gamma_dma.c 2004-06-15 23:10:00.755895843 -0700 +++ linux-2.6.7/drivers/char/drm/gamma_dma.c 2004-06-15 23:10:27.009000977 -0700 @@ -346,6 +346,9 @@ drm_buf_t *buf; drm_buf_t *last_buf = NULL; drm_device_dma_t *dma = dev->dma; + int *send_indices = NULL; + int *send_sizes = NULL; + DECLARE_WAITQUEUE(entry, current); /* Turn off interrupt handling */ @@ -365,11 +368,31 @@ ++must_free; } + send_indices = DRM(alloc)(d->send_count * sizeof(*send_indices), + DRM_MEM_DRIVER); + if (send_indices == NULL) + return -ENOMEM; + if (copy_from_user(send_indices, d->send_indices, + d->send_count * sizeof(*send_indices))) { + retcode = -EFAULT; + goto cleanup; + } + + send_sizes = DRM(alloc)(d->send_count * sizeof(*send_sizes), + DRM_MEM_DRIVER); + if (send_sizes == NULL) + return -ENOMEM; + if (copy_from_user(send_sizes, d->send_sizes, + d->send_count * sizeof(*send_sizes))) { + retcode = -EFAULT; + goto cleanup; + } + for (i = 0; i < d->send_count; i++) { - idx = d->send_indices[i]; + idx = send_indices[i]; if (idx < 0 || idx >= dma->buf_count) { DRM_ERROR("Index %d (of %d max)\n", - d->send_indices[i], dma->buf_count - 1); + send_indices[i], dma->buf_count - 1); continue; } buf = dma->buflist[ idx ]; @@ -391,7 +414,7 @@ process closes the /dev/drm? handle, so it can't also be doing DMA. */ buf->list = DRM_LIST_PRIO; - buf->used = d->send_sizes[i]; + buf->used = send_sizes[i]; buf->context = d->context; buf->while_locked = d->flags & _DRM_DMA_WHILE_LOCKED; address = (unsigned long)buf->address; @@ -402,14 +425,14 @@ if (buf->pending) { DRM_ERROR("Sending pending buffer:" " buffer %d, offset %d\n", - d->send_indices[i], i); + send_indices[i], i); retcode = -EINVAL; goto cleanup; } if (buf->waiting) { DRM_ERROR("Sending waiting buffer:" " buffer %d, offset %d\n", - d->send_indices[i], i); + send_indices[i], i); retcode = -EINVAL; goto cleanup; } @@ -458,6 +481,12 @@ gamma_dma_ready(dev); gamma_free_buffer(dev, last_buf); } + if (send_indices) + DRM(free)(send_indices, d->send_count * sizeof(*send_indices), + DRM_MEM_DRIVER); + if (send_sizes) + DRM(free)(send_sizes, d->send_count * sizeof(*send_sizes), + DRM_MEM_DRIVER); if (must_free && !dev->context_flag) { if (gamma_lock_free(dev, &dev->lock.hw_lock->lock, @@ -476,9 +505,13 @@ drm_buf_t *last_buf = NULL; int retcode = 0; drm_device_dma_t *dma = dev->dma; + int send_index; + + if (get_user(send_index, &d->send_indices[d->send_count-1])) + return -EFAULT; if (d->flags & _DRM_DMA_BLOCK) { - last_buf = dma->buflist[d->send_indices[d->send_count-1]]; + last_buf = dma->buflist[send_index]; add_wait_queue(&last_buf->dma_wait, &entry); } diff -urN linux-2.6.7-rc3/drivers/char/watchdog/pcwd.c linux-2.6.7/drivers/char/watchdog/pcwd.c --- linux-2.6.7-rc3/drivers/char/watchdog/pcwd.c 2004-06-15 23:10:00.830898999 -0700 +++ linux-2.6.7/drivers/char/watchdog/pcwd.c 2004-06-15 23:10:27.085004177 -0700 @@ -70,7 +70,7 @@ #include #include -#define WD_VER "1.16 (03/27/2004)" +#define WD_VER "1.16 (06/12/2004)" #define PFX "pcwd: " /* @@ -299,10 +299,11 @@ return 0; } -static void pcwd_keepalive(void) +static int pcwd_keepalive(void) { /* user land ping */ next_heartbeat = jiffies + (heartbeat * HZ); + return 0; } static int pcwd_set_heartbeat(int t) @@ -529,12 +530,12 @@ { if (expect_close == 42) { pcwd_stop(); - atomic_inc( &open_allowed ); } else { printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); pcwd_keepalive(); } expect_close = 0; + atomic_inc( &open_allowed ); return 0; } diff -urN linux-2.6.7-rc3/drivers/char/watchdog/pcwd_pci.c linux-2.6.7/drivers/char/watchdog/pcwd_pci.c --- linux-2.6.7-rc3/drivers/char/watchdog/pcwd_pci.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/drivers/char/watchdog/pcwd_pci.c 2004-06-15 23:10:27.085004177 -0700 @@ -49,7 +49,7 @@ /* Module and version information */ #define WATCHDOG_VERSION "1.00" -#define WATCHDOG_DATE "13/03/2004" +#define WATCHDOG_DATE "12 Jun 2004" #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog" #define WATCHDOG_NAME "pcwd_pci" #define PFX WATCHDOG_NAME ": " @@ -73,7 +73,7 @@ #define WD_PCI_TTRP 0x04 /* Temperature Trip status */ /* according to documentation max. time to process a command for the pci - watchdog card is 100 ms, so we give it 150 ms to do it's job */ + * watchdog card is 100 ms, so we give it 150 ms to do it's job */ #define PCI_COMMAND_TIMEOUT 150 /* Watchdog's internal commands */ @@ -404,8 +404,8 @@ printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); pcipcwd_keepalive(); } - clear_bit(0, &is_active); expect_release = 0; + clear_bit(0, &is_active); return 0; } @@ -585,15 +585,12 @@ printk(KERN_INFO PFX "No previous trip detected - Cold boot or reset\n"); /* Check that the heartbeat value is within it's range ; if not reset to the default */ - if (heartbeat < 1 || heartbeat > 0xFFFF) { - heartbeat = WATCHDOG_HEARTBEAT; + if (pcipcwd_set_heartbeat(heartbeat)) { + pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT); printk(KERN_INFO PFX "heartbeat value must be 0" #define DRIVER_DESC "Berkshire USB-PC Watchdog driver" #define DRIVER_LICENSE "GPL" @@ -456,8 +457,8 @@ printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); usb_pcwd_keepalive(usb_pcwd_device); } - clear_bit(0, &is_active); expect_release = 0; + clear_bit(0, &is_active); return 0; } @@ -681,15 +682,12 @@ ((option_switches & 0x08) ? "ON" : "OFF")); /* Check that the heartbeat value is within it's range ; if not reset to the default */ - if (heartbeat < 1 || heartbeat > 0xFFFF) { - heartbeat = WATCHDOG_HEARTBEAT; + if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) { + usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT); printk(KERN_INFO PFX "heartbeat value must be 0exists = 0; /* Deregister */ - misc_deregister(&usb_pcwd_temperature_miscdev); misc_deregister(&usb_pcwd_miscdev); + misc_deregister(&usb_pcwd_temperature_miscdev); unregister_reboot_notifier(&usb_pcwd_notifier); up (&usb_pcwd->sem); @@ -791,7 +789,7 @@ return result; } - printk(KERN_INFO PFX DRIVER_DESC " " DRIVER_VERSION "\n"); + printk(KERN_INFO PFX DRIVER_DESC " v" DRIVER_VERSION " (" DRIVER_DATE ")\n"); return 0; } diff -urN linux-2.6.7-rc3/drivers/cpufreq/cpufreq.c linux-2.6.7/drivers/cpufreq/cpufreq.c --- linux-2.6.7-rc3/drivers/cpufreq/cpufreq.c 2004-06-15 23:10:00.834899168 -0700 +++ linux-2.6.7/drivers/cpufreq/cpufreq.c 2004-06-15 23:10:27.091004430 -0700 @@ -722,7 +722,12 @@ unsigned int target_freq, unsigned int relation) { - return cpufreq_driver->target(policy, target_freq, relation); + int retval = -EINVAL; + lock_cpu_hotplug(); + if (cpu_online(policy->cpu)) + retval = cpufreq_driver->target(policy, target_freq, relation); + unlock_cpu_hotplug(); + return retval; } EXPORT_SYMBOL_GPL(__cpufreq_driver_target); diff -urN linux-2.6.7-rc3/drivers/ide/ide-cd.c linux-2.6.7/drivers/ide/ide-cd.c --- linux-2.6.7-rc3/drivers/ide/ide-cd.c 2004-06-15 23:10:00.870900683 -0700 +++ linux-2.6.7/drivers/ide/ide-cd.c 2004-06-15 23:10:27.306013482 -0700 @@ -535,9 +535,7 @@ rq->flags = REQ_PC; } -static void cdrom_queue_request_sense(ide_drive_t *drive, - struct completion *wait, - void *sense, +static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct request *failed_command) { struct cdrom_info *info = drive->driver_data; @@ -554,7 +552,6 @@ rq->cmd[4] = rq->data_len = 18; rq->flags = REQ_SENSE; - rq->waiting = wait; /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; @@ -574,7 +571,7 @@ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; /* retry only "normal" I/O: */ - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) { + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { rq->errors = 1; ide_end_drive_cmd(drive, stat, err); return ide_stopped; @@ -608,7 +605,7 @@ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; /* retry only "normal" I/O: */ - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) { + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { rq->errors = 1; ide_end_drive_cmd(drive, BUSY_STAT, 0); return ide_stopped; @@ -631,10 +628,21 @@ struct request *failed = (struct request *) rq->buffer; struct cdrom_info *info = drive->driver_data; void *sense = &info->sense_data; - - if (failed && failed->sense) { - sense = failed->sense; - failed->sense_len = rq->sense_len; + unsigned long flags; + + if (failed) { + if (failed->sense) { + sense = failed->sense; + failed->sense_len = rq->sense_len; + } + + /* + * now end failed request + */ + spin_lock_irqsave(&ide_lock, flags); + end_that_request_chunk(failed, 0, failed->data_len); + end_that_request_last(failed); + spin_unlock_irqrestore(&ide_lock, flags); } cdrom_analyze_sense_data(drive, failed, sense); @@ -642,6 +650,9 @@ if (!rq->current_nr_sectors && blk_fs_request(rq)) uptodate = 1; + /* make sure it's fully ended */ + if (blk_pc_request(rq)) + nsectors = (rq->data_len + 511) >> 9; if (!nsectors) nsectors = 1; @@ -684,7 +695,7 @@ } else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) { /* All other functions, except for READ. */ - struct completion *wait = NULL; + unsigned long flags; /* * if we have an error, pass back CHECK_CONDITION as the @@ -706,30 +717,23 @@ ide_dump_status(drive, "packet command error", stat); } - /* Set the error flag and complete the request. - Then, if we have a CHECK CONDITION status, - queue a request sense command. We must be careful, - though: we don't want the thread in - cdrom_queue_packet_command to wake up until - the request sense has completed. We do this - by transferring the semaphore from the packet - command request to the request sense request. */ - rq->flags |= REQ_FAILED; - if ((stat & ERR_STAT) != 0) { - wait = rq->waiting; - rq->waiting = NULL; - if ((rq->flags & REQ_BLOCK_PC) != 0) { - cdrom_queue_request_sense(drive, wait, - rq->sense, rq); - return 1; /* REQ_BLOCK_PC self-cares */ - } - } - cdrom_end_request(drive, 0); + /* + * instead of playing games with moving completions around, + * remove failed request completely and end it when the + * request sense has completed + */ + if (stat & ERR_STAT) { + spin_lock_irqsave(&ide_lock, flags); + blkdev_dequeue_request(rq); + HWGROUP(drive)->rq = NULL; + spin_unlock_irqrestore(&ide_lock, flags); + + cdrom_queue_request_sense(drive, rq->sense, rq); + } else + cdrom_end_request(drive, 0); - if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, wait, rq->sense, rq); } else if (blk_fs_request(rq)) { int do_end_request = 0; @@ -818,7 +822,7 @@ /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, NULL, NULL, NULL); + cdrom_queue_request_sense(drive, NULL, NULL); } else { blk_dump_rq_flags(rq, "ide-cd: bad rq"); cdrom_end_request(drive, 0); @@ -1666,14 +1670,8 @@ dma_error = HWIF(drive)->ide_dma_end(drive); } - if (cdrom_decode_status(drive, 0, &stat)) { - if ((stat & ERR_STAT) != 0) { - end_that_request_chunk(rq, 0, rq->data_len); - goto end_request; /* purge the whole thing... */ - } - end_that_request_chunk(rq, 1, rq->data_len); + if (cdrom_decode_status(drive, 0, &stat)) return ide_stopped; - } /* * using dma, transfer is complete now diff -urN linux-2.6.7-rc3/drivers/ide/ide-pnp.c linux-2.6.7/drivers/ide/ide-pnp.c --- linux-2.6.7-rc3/drivers/ide/ide-pnp.c 2004-05-09 19:32:52.000000000 -0700 +++ linux-2.6.7/drivers/ide/ide-pnp.c 2004-06-15 23:10:27.390017018 -0700 @@ -16,25 +16,9 @@ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include - #include - -#define GENERIC_HD_DATA 0 -#define GENERIC_HD_ERROR 1 -#define GENERIC_HD_NSECTOR 2 -#define GENERIC_HD_SECTOR 3 -#define GENERIC_HD_LCYL 4 -#define GENERIC_HD_HCYL 5 -#define GENERIC_HD_SELECT 6 -#define GENERIC_HD_STATUS 7 - -static int generic_ide_offsets[IDE_NR_PORTS] = { - GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, - GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL, - GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1 -}; +#include /* Add your devices here :)) */ struct pnp_device_id idepnp_devices[] = { @@ -52,12 +36,11 @@ if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) return -1; - ide_setup_ports(&hw, (unsigned long) pnp_port_start(dev, 0), - generic_ide_offsets, - (unsigned long) pnp_port_start(dev, 1), - 0, NULL, -// generic_pnp_ide_iops, - pnp_irq(dev, 0)); + memset(&hw, 0, sizeof(hw)); + ide_std_init_ports(&hw, pnp_port_start(dev, 0), + pnp_port_start(dev, 1)); + hw.irq = pnp_irq(dev, 0); + hw.dma = NO_DMA; index = ide_register_hw(&hw, &hwif); @@ -86,11 +69,7 @@ .remove = idepnp_remove, }; - -void pnpide_init(int enable) +void __init pnpide_init(void) { - if(enable) - pnp_register_driver(&idepnp_driver); - else - pnp_unregister_driver(&idepnp_driver); + pnp_register_driver(&idepnp_driver); } diff -urN linux-2.6.7-rc3/drivers/ide/ide-proc.c linux-2.6.7/drivers/ide/ide-proc.c --- linux-2.6.7-rc3/drivers/ide/ide-proc.c 2004-06-15 23:10:00.880901104 -0700 +++ linux-2.6.7/drivers/ide/ide-proc.c 2004-06-15 23:10:27.393017145 -0700 @@ -233,27 +233,6 @@ } #endif /* CONFIG_BLK_DEV_IDEPCI */ } else { /* not pci */ -#if !defined(__mc68000__) && !defined(CONFIG_APUS) - -/* -* Geert Uytterhoeven -* -* unless you can explain me what it really does. -* On m68k, we don't have outw() and outl() yet, -* and I need a good reason to implement it. -* -* BTW, IMHO the main remaining portability problem with the IDE driver -* is that it mixes IO (ioport) and MMIO (iomem) access on different platforms. -* -* I think all accesses should be done using -* -* ide_in[bwl](ide_device_instance, offset) -* ide_out[bwl](ide_device_instance, value, offset) -* -* so the architecture specific code can #define ide_{in,out}[bwl] to the -* appropriate function. -* -*/ switch (r->size) { case 1: hwif->OUTB(val, reg); break; @@ -262,7 +241,6 @@ case 4: hwif->OUTL(val, reg); break; } -#endif /* !__mc68000__ && !CONFIG_APUS */ } } spin_unlock_irqrestore(&ide_lock, flags); diff -urN linux-2.6.7-rc3/drivers/ide/ide-taskfile.c linux-2.6.7/drivers/ide/ide-taskfile.c --- linux-2.6.7-rc3/drivers/ide/ide-taskfile.c 2004-06-15 23:10:00.881901146 -0700 +++ linux-2.6.7/drivers/ide/ide-taskfile.c 2004-06-15 23:10:27.445019334 -0700 @@ -301,38 +301,18 @@ */ #ifndef CONFIG_IDE_TASKFILE_IO -#define task_map_rq(rq, flags) ide_map_buffer((rq), (flags)) -#define task_unmap_rq(rq, buf, flags) ide_unmap_buffer((rq), (buf), (flags)) - /* * Handler for command with PIO data-in phase, READ */ -/* - * FIXME before 2.4 enable ... - * DATA integrity issue upon error. - */ ide_startstop_t task_in_intr (ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; ide_hwif_t *hwif = HWIF(drive); char *pBuf = NULL; u8 stat; - unsigned long flags; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { -#if 0 - DTF("%s: attempting to recover last " \ - "sector counter status=0x%02x\n", - drive->name, stat); - /* - * Expect a BUG BOMB if we attempt to rewind the - * offset in the BH aka PAGE in the current BLOCK - * segment. This is different than the HOST segment. - */ -#endif - if (!rq->bio) - rq->current_nr_sectors++; return DRIVER(drive)->error(drive, "task_in_intr", stat); } if (!(stat & BUSY_STAT)) { @@ -343,17 +323,12 @@ } } - pBuf = task_map_rq(rq, &flags); + pBuf = rq->buffer + task_rq_offset(rq); DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n", pBuf, (int) rq->current_nr_sectors, stat); taskfile_input_data(drive, pBuf, SECTOR_WORDS); - task_unmap_rq(rq, pBuf, &flags); - /* - * FIXME :: We really can not legally get a new page/bh - * regardless, if this is the end of our segment. - * BH walking or segment can only be updated after we have a good - * hwif->INB(IDE_STATUS_REG); return. - */ + + /* FIXME: check drive status */ if (--rq->current_nr_sectors <= 0) if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; @@ -378,21 +353,10 @@ char *pBuf = NULL; unsigned int msect = drive->mult_count; unsigned int nsect; - unsigned long flags; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { - if (!rq->bio) { - rq->current_nr_sectors += drive->mult_count; - /* - * NOTE: could rewind beyond beginning :-/ - */ - } else { - printk(KERN_ERR "%s: MULTI-READ assume all data " \ - "transfered is bad status=0x%02x\n", - drive->name, stat); - } return DRIVER(drive)->error(drive, "task_mulin_intr", stat); } /* no data yet, so wait for another interrupt */ @@ -405,21 +369,16 @@ nsect = rq->current_nr_sectors; if (nsect > msect) nsect = msect; - pBuf = task_map_rq(rq, &flags); + pBuf = rq->buffer + task_rq_offset(rq); DTF("Multiread: %p, nsect: %d, msect: %d, " \ " rq->current_nr_sectors: %d\n", pBuf, nsect, msect, rq->current_nr_sectors); taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS); - task_unmap_rq(rq, pBuf, &flags); rq->errors = 0; rq->current_nr_sectors -= nsect; msect -= nsect; - /* - * FIXME :: We really can not legally get a new page/bh - * regardless, if this is the end of our segment. - * BH walking or segment can only be updated after we have a - * good hwif->INB(IDE_STATUS_REG); return. - */ + + /* FIXME: check drive status */ if (!rq->current_nr_sectors) { if (!DRIVER(drive)->end_request(drive, 1, 0)) return ide_stopped; @@ -438,8 +397,6 @@ */ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq) { - char *pBuf = NULL; - unsigned long flags; ide_startstop_t startstop; if (ide_wait_stat(&startstop, drive, DATA_READY, @@ -450,10 +407,8 @@ return startstop; } /* For Write_sectors we need to stuff the first sector */ - pBuf = task_map_rq(rq, &flags); - taskfile_output_data(drive, pBuf, SECTOR_WORDS); + taskfile_output_data(drive, rq->buffer + task_rq_offset(rq), SECTOR_WORDS); rq->current_nr_sectors--; - task_unmap_rq(rq, pBuf, &flags); return ide_started; } @@ -469,14 +424,9 @@ ide_hwif_t *hwif = HWIF(drive); struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; - unsigned long flags; u8 stat; if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), DRIVE_READY, drive->bad_wstat)) { - DTF("%s: WRITE attempting to recover last " \ - "sector counter status=0x%02x\n", - drive->name, stat); - rq->current_nr_sectors++; return DRIVER(drive)->error(drive, "task_out_intr", stat); } /* @@ -488,11 +438,10 @@ return ide_stopped; if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) { rq = HWGROUP(drive)->rq; - pBuf = task_map_rq(rq, &flags); + pBuf = rq->buffer + task_rq_offset(rq); DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); taskfile_output_data(drive, pBuf, SECTOR_WORDS); - task_unmap_rq(rq, pBuf, &flags); rq->errors = 0; rq->current_nr_sectors--; } @@ -503,18 +452,8 @@ EXPORT_SYMBOL(task_out_intr); -#undef ALTERNATE_STATE_DIAGRAM_MULTI_OUT - ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq) { -#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT - ide_hwif_t *hwif = HWIF(drive); - char *pBuf = NULL; - unsigned int nsect = 0, msect = drive->mult_count; - u8 stat; - unsigned long flags; -#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */ - ide_task_t *args = rq->special; ide_startstop_t startstop; @@ -525,31 +464,6 @@ drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE"); return startstop; } -#ifdef ALTERNATE_STATE_DIAGRAM_MULTI_OUT - - do { - nsect = rq->current_nr_sectors; - if (nsect > msect) - nsect = msect; - pBuf = task_map_rq(rq, &flags); - DTF("Pre-Multiwrite: %p, nsect: %d, msect: %d, " \ - "rq->current_nr_sectors: %ld\n", - pBuf, nsect, msect, rq->current_nr_sectors); - msect -= nsect; - taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - task_unmap_rq(rq, pBuf, &flags); - rq->current_nr_sectors -= nsect; - if (!rq->current_nr_sectors) { - if (!DRIVER(drive)->end_request(drive, 1, 0)) - if (!rq->bio) { - stat = hwif->INB(IDE_STATUS_REG); - return ide_stopped; - } - } - } while (msect); - rq->errors = 0; - return ide_started; -#else /* ! ALTERNATE_STATE_DIAGRAM_MULTI_OUT */ if (!(drive_is_ready(drive))) { int i; for (i=0; i<100; i++) { @@ -563,15 +477,11 @@ * move the DATA-TRANSFER T-Bar as BSY != 0. */ return args->handler(drive); -#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */ } EXPORT_SYMBOL(pre_task_mulout_intr); /* - * FIXME before enabling in 2.4 ... DATA integrity issue upon error. - */ -/* * Handler for command write multiple * Called directly from execute_drive_cmd for the first bunch of sectors, * afterwards only by the ISR @@ -582,49 +492,17 @@ u8 stat = hwif->INB(IDE_STATUS_REG); struct request *rq = HWGROUP(drive)->rq; char *pBuf = NULL; - ide_startstop_t startstop = ide_stopped; unsigned int msect = drive->mult_count; unsigned int nsect; - unsigned long flags; - /* - * (ks/hs): Handle last IRQ on multi-sector transfer, - * occurs after all data was sent in this chunk - */ - if (rq->current_nr_sectors == 0) { + if (!OK_STAT(stat, DATA_READY, BAD_R_STAT) || !rq->current_nr_sectors) { if (stat & (ERR_STAT|DRQ_STAT)) { - if (!rq->bio) { - rq->current_nr_sectors += drive->mult_count; - /* - * NOTE: could rewind beyond beginning :-/ - */ - } else { - printk(KERN_ERR "%s: MULTI-WRITE assume all data " \ - "transfered is bad status=0x%02x\n", - drive->name, stat); - } return DRIVER(drive)->error(drive, "task_mulout_intr", stat); } - if (!rq->bio) + /* Handle last IRQ, occurs after all data was sent. */ + if (!rq->current_nr_sectors) { DRIVER(drive)->end_request(drive, 1, 0); - return startstop; - } - /* - * DON'T be lazy code the above and below togather !!! - */ - if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) { - if (stat & (ERR_STAT|DRQ_STAT)) { - if (!rq->bio) { - rq->current_nr_sectors += drive->mult_count; - /* - * NOTE: could rewind beyond beginning :-/ - */ - } else { - printk("%s: MULTI-WRITE assume all data " \ - "transfered is bad status=0x%02x\n", - drive->name, stat); - } - return DRIVER(drive)->error(drive, "task_mulout_intr", stat); + return ide_stopped; } /* no data yet, so wait for another interrupt */ if (HWGROUP(drive)->handler == NULL) @@ -632,7 +510,6 @@ return ide_started; } -#ifndef ALTERNATE_STATE_DIAGRAM_MULTI_OUT if (HWGROUP(drive)->handler != NULL) { unsigned long lflags; spin_lock_irqsave(&ide_lock, lflags); @@ -640,26 +517,20 @@ del_timer(&HWGROUP(drive)->timer); spin_unlock_irqrestore(&ide_lock, lflags); } -#endif /* ALTERNATE_STATE_DIAGRAM_MULTI_OUT */ do { nsect = rq->current_nr_sectors; if (nsect > msect) nsect = msect; - pBuf = task_map_rq(rq, &flags); + pBuf = rq->buffer + task_rq_offset(rq); DTF("Multiwrite: %p, nsect: %d, msect: %d, " \ "rq->current_nr_sectors: %ld\n", pBuf, nsect, msect, rq->current_nr_sectors); msect -= nsect; taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); - task_unmap_rq(rq, pBuf, &flags); rq->current_nr_sectors -= nsect; - /* - * FIXME :: We really can not legally get a new page/bh - * regardless, if this is the end of our segment. - * BH walking or segment can only be updated after we - * have a good hwif->INB(IDE_STATUS_REG); return. - */ + + /* FIXME: check drive status */ if (!rq->current_nr_sectors) { if (!DRIVER(drive)->end_request(drive, 1, 0)) if (!rq->bio) @@ -975,6 +846,12 @@ else rq.nr_sectors = data_size / SECTOR_SIZE; + if (!rq.nr_sectors) { + printk(KERN_ERR "%s: in/out command without data\n", + drive->name); + return -EFAULT; + } + rq.hard_nr_sectors = rq.nr_sectors; rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; } @@ -1459,9 +1336,6 @@ char *pBuf = NULL; int retries = 5; - if (rq->current_nr_sectors == 0) - return DRIVER(drive)->error(drive, "flagged_task_in_intr (no data requested)", stat); - if (!OK_STAT(stat, DATA_READY, BAD_R_STAT)) { if (stat & ERR_STAT) { return DRIVER(drive)->error(drive, "flagged_task_in_intr", stat); @@ -1508,9 +1382,6 @@ int retries = 5; unsigned int msect, nsect; - if (rq->current_nr_sectors == 0) - return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (no data requested)", stat); - msect = drive->mult_count; if (msect == 0) return DRIVER(drive)->error(drive, "flagged_task_mulin_intr (multimode not set)", stat); @@ -1562,14 +1433,8 @@ */ ide_startstop_t flagged_pre_task_out_intr (ide_drive_t *drive, struct request *rq) { - ide_hwif_t *hwif = HWIF(drive); - u8 stat = hwif->INB(IDE_STATUS_REG); ide_startstop_t startstop; - if (!rq->current_nr_sectors) { - return DRIVER(drive)->error(drive, "flagged_pre_task_out_intr (write data not specified)", stat); - } - if (ide_wait_stat(&startstop, drive, DATA_READY, BAD_W_STAT, WAIT_DRQ)) { printk(KERN_ERR "%s: No DRQ bit after issuing write command.\n", drive->name); @@ -1631,9 +1496,6 @@ ide_startstop_t startstop; unsigned int msect, nsect; - if (!rq->current_nr_sectors) - return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (write data not specified)", stat); - msect = drive->mult_count; if (msect == 0) return DRIVER(drive)->error(drive, "flagged_pre_task_mulout_intr (multimode not set)", stat); diff -urN linux-2.6.7-rc3/drivers/ide/ide.c linux-2.6.7/drivers/ide/ide.c --- linux-2.6.7-rc3/drivers/ide/ide.c 2004-06-15 23:10:00.888901441 -0700 +++ linux-2.6.7/drivers/ide/ide.c 2004-06-15 23:10:27.488021144 -0700 @@ -2003,6 +2003,7 @@ return 1; } +extern void pnpide_init(void); extern void h8300_ide_init(void); /* @@ -2069,12 +2070,9 @@ buddha_init(); } #endif /* CONFIG_BLK_DEV_BUDDHA */ -#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) - { - extern void pnpide_init(int enable); - pnpide_init(1); - } -#endif /* CONFIG_BLK_DEV_IDEPNP */ +#ifdef CONFIG_BLK_DEV_IDEPNP + pnpide_init(); +#endif #ifdef CONFIG_H8300 h8300_ide_init(); #endif @@ -2212,9 +2210,6 @@ up(&ide_setting_sem); return 1; } -#if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) && defined(MODULE) - pnpide_init(0); -#endif /* CONFIG_BLK_DEV_IDEPNP */ #ifdef CONFIG_PROC_FS ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); ide_remove_proc_entries(drive->proc, generic_subdriver_entries); diff -urN linux-2.6.7-rc3/drivers/ide/pci/aec62xx.c linux-2.6.7/drivers/ide/pci/aec62xx.c --- linux-2.6.7-rc3/drivers/ide/pci/aec62xx.c 2004-06-15 23:10:00.889901483 -0700 +++ linux-2.6.7/drivers/ide/pci/aec62xx.c 2004-06-15 23:10:27.553023881 -0700 @@ -409,7 +409,7 @@ return 0; } -static unsigned int __init init_chipset_aec62xx (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) { int bus_speed = system_bus_clock(); @@ -435,7 +435,7 @@ return dev->irq; } -static void __init init_hwif_aec62xx (ide_hwif_t *hwif) +static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) { hwif->autodma = 0; hwif->tuneproc = &aec62xx_tune_drive; @@ -468,7 +468,7 @@ hwif->drives[1].autodma = hwif->autodma; } -static void __init init_dma_aec62xx (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase) { struct pci_dev *dev = hwif->pci_dev; @@ -490,12 +490,12 @@ ide_setup_dma(hwif, dmabase, 8); } -static void __init init_setup_aec62xx (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) { ide_setup_pci_device(dev, d); } -static void __init init_setup_aec6x80 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) { unsigned long bar4reg = pci_resource_start(dev, 4); diff -urN linux-2.6.7-rc3/drivers/ide/pci/alim15x3.c linux-2.6.7/drivers/ide/pci/alim15x3.c --- linux-2.6.7-rc3/drivers/ide/pci/alim15x3.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/ide/pci/alim15x3.c 2004-06-15 23:10:27.613026407 -0700 @@ -38,7 +38,7 @@ #include -#include "alim15x3.h" +#define DISPLAY_ALI_TIMINGS /* * ALi devices are not plug in. Otherwise these static values would @@ -853,6 +853,16 @@ ide_setup_dma(hwif, dmabase, 8); } +static ide_pci_device_t ali15x3_chipset __devinitdata = { + .name = "ALI15X3", + .init_chipset = init_chipset_ali15x3, + .init_hwif = init_hwif_ali15x3, + .init_dma = init_dma_ali15x3, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, +}; + /** * alim15x3_init_one - set up an ALi15x3 IDE controller * @dev: PCI device to set up @@ -863,8 +873,8 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d = &ali15x3_chipsets[id->driver_data]; - + ide_pci_device_t *d = &ali15x3_chipset; + if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL)) printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n"); diff -urN linux-2.6.7-rc3/drivers/ide/pci/alim15x3.h linux-2.6.7/drivers/ide/pci/alim15x3.h --- linux-2.6.7-rc3/drivers/ide/pci/alim15x3.h 2004-06-15 23:10:00.890901525 -0700 +++ linux-2.6.7/drivers/ide/pci/alim15x3.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,27 +0,0 @@ -#ifndef ALI15X3_H -#define ALI15X3_H - -#include -#include -#include - -#define DISPLAY_ALI_TIMINGS - -static unsigned int init_chipset_ali15x3(struct pci_dev *, const char *); -static void init_hwif_common_ali15x3(ide_hwif_t *); -static void init_hwif_ali15x3(ide_hwif_t *); -static void init_dma_ali15x3(ide_hwif_t *, unsigned long); - -static ide_pci_device_t ali15x3_chipsets[] __devinitdata = { - { /* 0 */ - .name = "ALI15X3", - .init_chipset = init_chipset_ali15x3, - .init_hwif = init_hwif_ali15x3, - .init_dma = init_dma_ali15x3, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* ALI15X3 */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/cmd64x.c linux-2.6.7/drivers/ide/pci/cmd64x.c --- linux-2.6.7-rc3/drivers/ide/pci/cmd64x.c 2004-06-15 23:10:00.894901693 -0700 +++ linux-2.6.7/drivers/ide/pci/cmd64x.c 2004-06-15 23:10:27.692029734 -0700 @@ -586,7 +586,7 @@ return (dma_stat & 7) != 4; } -static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name) { u32 class_rev = 0; u8 mrdmode = 0; @@ -674,7 +674,7 @@ return 0; } -static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif) +static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) { u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01; @@ -689,7 +689,7 @@ return (ata66 & mask) ? 1 : 0; } -static void __init init_hwif_cmd64x (ide_hwif_t *hwif) +static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int class_rev; diff -urN linux-2.6.7-rc3/drivers/ide/pci/cs5520.c linux-2.6.7/drivers/ide/pci/cs5520.c --- linux-2.6.7-rc3/drivers/ide/pci/cs5520.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/drivers/ide/pci/cs5520.c 2004-06-15 23:10:27.710030491 -0700 @@ -51,7 +51,7 @@ #include #include -#include "cs5520.h" +#define DISPLAY_CS5520_TIMINGS #if defined(DISPLAY_CS5520_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -251,7 +251,24 @@ hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; } - + +#define DECLARE_CS_DEV(name_str) \ + { \ + .name = name_str, \ + .init_chipset = init_chipset_cs5520, \ + .init_setup_dma = cs5520_init_setup_dma, \ + .init_hwif = init_hwif_cs5520, \ + .channels = 2, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + .flags = IDEPCI_FLAG_ISA_PORTS, \ + } + +static ide_pci_device_t cyrix_chipsets[] __devinitdata = { + /* 0 */ DECLARE_CS_DEV("Cyrix 5510"), + /* 1 */ DECLARE_CS_DEV("Cyrix 5520") +}; + /* * The 5510/5520 are a bit weird. They don't quite set up the way * the PCI helper layer expects so we must do much of the set up diff -urN linux-2.6.7-rc3/drivers/ide/pci/cs5520.h linux-2.6.7/drivers/ide/pci/cs5520.h --- linux-2.6.7-rc3/drivers/ide/pci/cs5520.h 2004-06-15 23:10:00.895901735 -0700 +++ linux-2.6.7/drivers/ide/pci/cs5520.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,40 +0,0 @@ -#ifndef CS5520_H -#define CS5520_H - -#include -#include -#include - -#define DISPLAY_CS5520_TIMINGS - -static unsigned int init_chipset_cs5520(struct pci_dev *, const char *); -static void init_hwif_cs5520(ide_hwif_t *); -static void cs5520_init_setup_dma(struct pci_dev *dev, struct ide_pci_device_s *d, ide_hwif_t *hwif); - -static ide_pci_device_t cyrix_chipsets[] __devinitdata = { - { - .name = "Cyrix 5510", - .init_chipset = init_chipset_cs5520, - .init_setup_dma = cs5520_init_setup_dma, - .init_hwif = init_hwif_cs5520, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - .flags = IDEPCI_FLAG_ISA_PORTS, - }, - { - .name = "Cyrix 5520", - .init_chipset = init_chipset_cs5520, - .init_setup_dma = cs5520_init_setup_dma, - .init_hwif = init_hwif_cs5520, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - .flags = IDEPCI_FLAG_ISA_PORTS, - } -}; - - -#endif /* CS5520_H */ - - diff -urN linux-2.6.7-rc3/drivers/ide/pci/cs5530.c linux-2.6.7/drivers/ide/pci/cs5530.c --- linux-2.6.7-rc3/drivers/ide/pci/cs5530.c 2004-06-15 23:10:00.896901778 -0700 +++ linux-2.6.7/drivers/ide/pci/cs5530.c 2004-06-15 23:10:27.712030576 -0700 @@ -31,7 +31,7 @@ #include #include -#include "cs5530.h" +#define DISPLAY_CS5530_TIMINGS #if defined(DISPLAY_CS5530_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -404,9 +404,19 @@ hwif->drives[1].autodma = hwif->autodma; } +static ide_pci_device_t cs5530_chipset __devinitdata = { + .name = "CS5530", + .init_chipset = init_chipset_cs5530, + .init_hwif = init_hwif_cs5530, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .flags = IDEPCI_FLAG_FORCE_MASTER, +}; + static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &cs5530_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &cs5530_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/cs5530.h linux-2.6.7/drivers/ide/pci/cs5530.h --- linux-2.6.7-rc3/drivers/ide/pci/cs5530.h 2004-06-15 23:10:00.896901778 -0700 +++ linux-2.6.7/drivers/ide/pci/cs5530.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,25 +0,0 @@ -#ifndef CS5530_H -#define CS5530_H - -#include -#include -#include - -#define DISPLAY_CS5530_TIMINGS - -static unsigned int init_chipset_cs5530(struct pci_dev *, const char *); -static void init_hwif_cs5530(ide_hwif_t *); - -static ide_pci_device_t cs5530_chipsets[] __devinitdata = { - { /* 0 */ - .name = "CS5530", - .init_chipset = init_chipset_cs5530, - .init_hwif = init_hwif_cs5530, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - .flags = IDEPCI_FLAG_FORCE_MASTER, - } -}; - -#endif /* CS5530_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/hpt34x.c linux-2.6.7/drivers/ide/pci/hpt34x.c --- linux-2.6.7-rc3/drivers/ide/pci/hpt34x.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/ide/pci/hpt34x.c 2004-06-15 23:10:27.755032386 -0700 @@ -235,7 +235,7 @@ */ #define HPT34X_PCI_INIT_REG 0x80 -static unsigned int __init init_chipset_hpt34x (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const char *name) { int i = 0; unsigned long hpt34xIoBase = pci_resource_start(dev, 4); @@ -289,7 +289,7 @@ return dev->irq; } -static void __init init_hwif_hpt34x (ide_hwif_t *hwif) +static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) { u16 pcicmd = 0; diff -urN linux-2.6.7-rc3/drivers/ide/pci/hpt366.c linux-2.6.7/drivers/ide/pci/hpt366.c --- linux-2.6.7-rc3/drivers/ide/pci/hpt366.c 2004-06-15 23:10:00.898901862 -0700 +++ linux-2.6.7/drivers/ide/pci/hpt366.c 2004-06-15 23:10:27.756032428 -0700 @@ -795,7 +795,7 @@ return 0; } -static int __init init_hpt37x(struct pci_dev *dev) +static int __devinit init_hpt37x(struct pci_dev *dev) { int adjust, i; u16 freq; @@ -923,7 +923,7 @@ return 0; } -static int __init init_hpt366 (struct pci_dev *dev) +static int __devinit init_hpt366(struct pci_dev *dev) { u32 reg1 = 0; u8 drive_fast = 0; @@ -958,7 +958,7 @@ return 0; } -static unsigned int __init init_chipset_hpt366 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name) { int ret = 0; u8 test = 0; @@ -1004,7 +1004,7 @@ return dev->irq; } -static void __init init_hwif_hpt366 (ide_hwif_t *hwif) +static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02; @@ -1116,7 +1116,7 @@ hwif->drives[1].autodma = hwif->autodma; } -static void __init init_dma_hpt366 (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) { u8 masterdma = 0, slavedma = 0; u8 dma_new = 0, dma_old = 0; @@ -1151,7 +1151,7 @@ ide_setup_dma(hwif, dmabase, 8); } -static void __init init_setup_hpt374 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d) { struct pci_dev *findev = NULL; @@ -1176,12 +1176,12 @@ ide_setup_pci_device(dev, d); } -static void __init init_setup_hpt37x (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d) { ide_setup_pci_device(dev, d); } -static void __init init_setup_hpt366 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) { struct pci_dev *findev = NULL; u8 pin1 = 0, pin2 = 0; diff -urN linux-2.6.7-rc3/drivers/ide/pci/ns87415.c linux-2.6.7/drivers/ide/pci/ns87415.c --- linux-2.6.7-rc3/drivers/ide/pci/ns87415.c 2004-06-15 23:10:00.900901946 -0700 +++ linux-2.6.7/drivers/ide/pci/ns87415.c 2004-06-15 23:10:27.758032512 -0700 @@ -25,8 +25,6 @@ #include -#include "ns87415.h" - static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; /* @@ -217,9 +215,17 @@ hwif->drives[1].autodma = hwif->autodma; } +static ide_pci_device_t ns87415_chipset __devinitdata = { + .name = "NS87415", + .init_hwif = init_hwif_ns87415, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, +}; + static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &ns87415_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &ns87415_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/ns87415.h linux-2.6.7/drivers/ide/pci/ns87415.h --- linux-2.6.7-rc3/drivers/ide/pci/ns87415.h 2004-06-15 23:10:00.900901946 -0700 +++ linux-2.6.7/drivers/ide/pci/ns87415.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,20 +0,0 @@ -#ifndef NS87415_H -#define NS87415_H - -#include -#include -#include - -static void init_hwif_ns87415(ide_hwif_t *); - -static ide_pci_device_t ns87415_chipsets[] __devinitdata = { - { /* 0 */ - .name = "NS87415", - .init_hwif = init_hwif_ns87415, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* NS87415_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/pdc202xx_new.c linux-2.6.7/drivers/ide/pci/pdc202xx_new.c --- linux-2.6.7-rc3/drivers/ide/pci/pdc202xx_new.c 2004-06-15 23:10:00.901901988 -0700 +++ linux-2.6.7/drivers/ide/pci/pdc202xx_new.c 2004-06-15 23:10:27.761032639 -0700 @@ -404,7 +404,7 @@ } #endif /* CONFIG_PPC_PMAC */ -static unsigned int __init init_chipset_pdcnew (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name) { if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, @@ -429,7 +429,7 @@ return dev->irq; } -static void __init init_hwif_pdc202new (ide_hwif_t *hwif) +static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) { hwif->autodma = 0; @@ -457,12 +457,12 @@ #endif /* PDC202_DEBUG_CABLE */ } -static void __init init_setup_pdcnew (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) { ide_setup_pci_device(dev, d); } -static void __init init_setup_pdc20270 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d) { struct pci_dev *findev = NULL; @@ -488,7 +488,7 @@ ide_setup_pci_device(dev, d); } -static void __init init_setup_pdc20276 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d) { if ((dev->bus->self) && (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && diff -urN linux-2.6.7-rc3/drivers/ide/pci/pdc202xx_old.c linux-2.6.7/drivers/ide/pci/pdc202xx_old.c --- linux-2.6.7-rc3/drivers/ide/pci/pdc202xx_old.c 2004-06-15 23:10:00.902902030 -0700 +++ linux-2.6.7/drivers/ide/pci/pdc202xx_old.c 2004-06-15 23:10:27.763032723 -0700 @@ -670,7 +670,7 @@ return 0; } -static unsigned int __init init_chipset_pdc202xx (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) { if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, @@ -715,7 +715,7 @@ return dev->irq; } -static void __init init_hwif_pdc202xx (ide_hwif_t *hwif) +static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) { hwif->autodma = 0; hwif->tuneproc = &config_chipset_for_pio; @@ -755,7 +755,7 @@ #endif /* PDC202_DEBUG_CABLE */ } -static void __init init_dma_pdc202xx (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) { u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0; @@ -807,7 +807,7 @@ ide_setup_dma(hwif, dmabase, 8); } -static void __init init_setup_pdc202ata4 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdc202ata4(struct pci_dev *dev, ide_pci_device_t *d) { if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { u8 irq = 0, irq2 = 0; @@ -837,7 +837,7 @@ ide_setup_pci_device(dev, d); } -static void __init init_setup_pdc20265 (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdc20265(struct pci_dev *dev, ide_pci_device_t *d) { if ((dev->bus->self) && (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && @@ -866,7 +866,7 @@ ide_setup_pci_device(dev, d); } -static void __init init_setup_pdc202xx (struct pci_dev *dev, ide_pci_device_t *d) +static void __devinit init_setup_pdc202xx(struct pci_dev *dev, ide_pci_device_t *d) { ide_setup_pci_device(dev, d); } diff -urN linux-2.6.7-rc3/drivers/ide/pci/piix.c linux-2.6.7/drivers/ide/pci/piix.c --- linux-2.6.7-rc3/drivers/ide/pci/piix.c 2004-06-15 23:10:00.903902072 -0700 +++ linux-2.6.7/drivers/ide/pci/piix.c 2004-06-15 23:10:27.764032765 -0700 @@ -650,8 +650,8 @@ * Set up the ide_hwif_t for the PIIX interface according to the * capabilities of the hardware. */ - -static void __init init_hwif_piix (ide_hwif_t *hwif) + +static void __devinit init_hwif_piix(ide_hwif_t *hwif) { u8 reg54h = 0, reg55h = 0, ata66 = 0; u8 mask = hwif->channel ? 0xc0 : 0x30; @@ -720,8 +720,8 @@ * Enable the xp fixup for the PIIX controller and then perform * a standard ide PCI setup */ - -static void __init init_setup_piix (struct pci_dev *dev, ide_pci_device_t *d) + +static void __devinit init_setup_piix(struct pci_dev *dev, ide_pci_device_t *d) { ide_setup_pci_device(dev, d); } @@ -749,8 +749,8 @@ * Check for the present of 450NX errata #19 and errata #25. If * they are found, disable use of DMA IDE */ - -static void __init piix_check_450nx(void) + +static void __devinit piix_check_450nx(void) { struct pci_dev *pdev = NULL; u16 cfg; diff -urN linux-2.6.7-rc3/drivers/ide/pci/rz1000.c linux-2.6.7/drivers/ide/pci/rz1000.c --- linux-2.6.7-rc3/drivers/ide/pci/rz1000.c 2004-06-15 23:10:00.904902114 -0700 +++ linux-2.6.7/drivers/ide/pci/rz1000.c 2004-06-15 23:10:27.765032807 -0700 @@ -33,8 +33,6 @@ #include -#include "rz1000.h" - static void __init init_hwif_rz1000 (ide_hwif_t *hwif) { u16 reg; @@ -54,15 +52,23 @@ } } +static ide_pci_device_t rz1000_chipset __devinitdata = { + .name = "RZ100x", + .init_hwif = init_hwif_rz1000, + .channels = 2, + .autodma = NODMA, + .bootable = ON_BOARD, +}; + static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &rz1000_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &rz1000_chipset); return 0; } static struct pci_device_id rz1000_pci_tbl[] = { { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl); diff -urN linux-2.6.7-rc3/drivers/ide/pci/rz1000.h linux-2.6.7/drivers/ide/pci/rz1000.h --- linux-2.6.7-rc3/drivers/ide/pci/rz1000.h 2004-06-15 23:10:00.904902114 -0700 +++ linux-2.6.7/drivers/ide/pci/rz1000.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,26 +0,0 @@ -#ifndef RZ100X_H -#define RZ100X_H - -#include -#include -#include - -static void init_hwif_rz1000(ide_hwif_t *); - -static ide_pci_device_t rz1000_chipsets[] __devinitdata = { - { - .name = "RZ1000", - .init_hwif = init_hwif_rz1000, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, - },{ - .name = "RZ1001", - .init_hwif = init_hwif_rz1000, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* RZ100X_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/sc1200.c linux-2.6.7/drivers/ide/pci/sc1200.c --- linux-2.6.7-rc3/drivers/ide/pci/sc1200.c 2004-06-15 23:10:00.905902156 -0700 +++ linux-2.6.7/drivers/ide/pci/sc1200.c 2004-06-15 23:10:27.767032891 -0700 @@ -29,8 +29,6 @@ #include #include -#include "sc1200.h" - #define SC1200_REV_A 0x00 #define SC1200_REV_B1 0x01 #define SC1200_REV_B3 0x02 @@ -545,9 +543,18 @@ hwif->drives[1].autodma = hwif->autodma; } +static ide_pci_device_t sc1200_chipset __devinitdata = { + .name = "SC1200", + .init_chipset = init_chipset_sc1200, + .init_hwif = init_hwif_sc1200, + .channels = 2, + .autodma = AUTODMA, + .bootable = ON_BOARD, +}; + static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &sc1200_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &sc1200_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/sc1200.h linux-2.6.7/drivers/ide/pci/sc1200.h --- linux-2.6.7-rc3/drivers/ide/pci/sc1200.h 2004-06-15 23:10:00.905902156 -0700 +++ linux-2.6.7/drivers/ide/pci/sc1200.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,24 +0,0 @@ -#ifndef SC1200_H -#define SC1200_H - -#include -#include -#include - -#define DISPLAY_SC1200_TIMINGS - -static unsigned int init_chipset_sc1200(struct pci_dev *, const char *); -static void init_hwif_sc1200(ide_hwif_t *); - -static ide_pci_device_t sc1200_chipsets[] __devinitdata = { - { /* 0 */ - .name = "SC1200", - .init_chipset = init_chipset_sc1200, - .init_hwif = init_hwif_sc1200, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* SC1200_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/siimage.c linux-2.6.7/drivers/ide/pci/siimage.c --- linux-2.6.7-rc3/drivers/ide/pci/siimage.c 2004-06-15 23:10:00.908902283 -0700 +++ linux-2.6.7/drivers/ide/pci/siimage.c 2004-06-15 23:10:27.771033060 -0700 @@ -31,7 +31,8 @@ #include -#include "siimage.h" +#undef SIIMAGE_VIRTUAL_DMAPIO +#undef SIIMAGE_LARGE_DMA /** * pdev_is_sata - check if device is SATA @@ -812,7 +813,7 @@ * to 133MHz clocking if the system isn't already set up to do it. */ -static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name) { u32 class_rev = 0; u8 tmpbyte = 0; @@ -877,8 +878,8 @@ * The hardware supports buffered taskfiles and also some rather nice * extended PRD tables. Unfortunately right now we don't. */ - -static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) + +static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; void *addr = pci_get_drvdata(dev); @@ -996,8 +997,8 @@ * look in we get for setting up the hwif so that we * can get the iops right before using them. */ - -static void __init init_iops_siimage (ide_hwif_t *hwif) + +static void __devinit init_iops_siimage(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u32 class_rev = 0; @@ -1023,8 +1024,8 @@ * Check for the presence of an ATA66 capable cable on the * interface. */ - -static unsigned int __init ata66_siimage (ide_hwif_t *hwif) + +static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif) { unsigned long addr = siimage_selreg(hwif, 0); if (pci_get_drvdata(hwif->pci_dev) == NULL) { @@ -1044,8 +1045,8 @@ * requires several custom handlers so we override the default * ide DMA handlers appropriately */ - -static void __init init_hwif_siimage (ide_hwif_t *hwif) + +static void __devinit init_hwif_siimage(ide_hwif_t *hwif) { hwif->autodma = 0; @@ -1092,6 +1093,23 @@ hwif->drives[1].autodma = hwif->autodma; } +#define DECLARE_SII_DEV(name_str) \ + { \ + .name = name_str, \ + .init_chipset = init_chipset_siimage, \ + .init_iops = init_iops_siimage, \ + .init_hwif = init_hwif_siimage, \ + .channels = 2, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + } + +static ide_pci_device_t siimage_chipsets[] __devinitdata = { + /* 0 */ DECLARE_SII_DEV("SiI680"), + /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"), + /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA") +}; + /** * siimage_init_one - pci layer discovery entry * @dev: PCI device diff -urN linux-2.6.7-rc3/drivers/ide/pci/siimage.h linux-2.6.7/drivers/ide/pci/siimage.h --- linux-2.6.7-rc3/drivers/ide/pci/siimage.h 2004-06-15 23:10:00.908902283 -0700 +++ linux-2.6.7/drivers/ide/pci/siimage.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,53 +0,0 @@ -#ifndef SIIMAGE_H -#define SIIMAGE_H - -#include -#include - -#include - -#undef SIIMAGE_VIRTUAL_DMAPIO -#undef SIIMAGE_BUFFERED_TASKFILE -#undef SIIMAGE_LARGE_DMA - -#define SII_DEBUG 0 - -#if SII_DEBUG -#define siiprintk(x...) printk(x) -#else -#define siiprintk(x...) -#endif - -static unsigned int init_chipset_siimage(struct pci_dev *, const char *); -static void init_iops_siimage(ide_hwif_t *); -static void init_hwif_siimage(ide_hwif_t *); - -static ide_pci_device_t siimage_chipsets[] __devinitdata = { - { /* 0 */ - .name = "SiI680", - .init_chipset = init_chipset_siimage, - .init_iops = init_iops_siimage, - .init_hwif = init_hwif_siimage, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 1 */ - .name = "SiI3112 Serial ATA", - .init_chipset = init_chipset_siimage, - .init_iops = init_iops_siimage, - .init_hwif = init_hwif_siimage, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 2 */ - .name = "Adaptec AAR-1210SA", - .init_chipset = init_chipset_siimage, - .init_iops = init_iops_siimage, - .init_hwif = init_hwif_siimage, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* SIIMAGE_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/sis5513.c linux-2.6.7/drivers/ide/pci/sis5513.c --- linux-2.6.7-rc3/drivers/ide/pci/sis5513.c 2004-06-15 23:10:00.909902325 -0700 +++ linux-2.6.7/drivers/ide/pci/sis5513.c 2004-06-15 23:10:27.773033144 -0700 @@ -63,7 +63,8 @@ #include #include "ide-timing.h" -#include "sis5513.h" + +#define DISPLAY_SIS_TIMINGS /* registers layout and init values are chipset family dependant */ @@ -944,9 +945,19 @@ return; } +static ide_pci_device_t sis5513_chipset __devinitdata = { + .name = "SIS5513", + .init_chipset = init_chipset_sis5513, + .init_hwif = init_hwif_sis5513, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, + .bootable = ON_BOARD, +}; + static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &sis5513_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &sis5513_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/sis5513.h linux-2.6.7/drivers/ide/pci/sis5513.h --- linux-2.6.7-rc3/drivers/ide/pci/sis5513.h 2004-06-15 23:10:00.909902325 -0700 +++ linux-2.6.7/drivers/ide/pci/sis5513.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,25 +0,0 @@ -#ifndef SIS5513_H -#define SIS5513_H - -#include -#include -#include - -#define DISPLAY_SIS_TIMINGS - -static unsigned int init_chipset_sis5513(struct pci_dev *, const char *); -static void init_hwif_sis5513(ide_hwif_t *); - -static ide_pci_device_t sis5513_chipsets[] __devinitdata = { - { /* 0 */ - .name = "SIS5513", - .init_chipset = init_chipset_sis5513, - .init_hwif = init_hwif_sis5513, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .bootable = ON_BOARD, - } -}; - -#endif /* SIS5513_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/sl82c105.c linux-2.6.7/drivers/ide/pci/sl82c105.c --- linux-2.6.7-rc3/drivers/ide/pci/sl82c105.c 2004-06-15 23:10:00.909902325 -0700 +++ linux-2.6.7/drivers/ide/pci/sl82c105.c 2004-06-15 23:10:27.775033228 -0700 @@ -29,8 +29,6 @@ #include #include -#include "sl82c105.h" - #undef DEBUG #ifdef DEBUG @@ -481,9 +479,20 @@ #endif /* CONFIG_BLK_DEV_IDEDMA */ } +static ide_pci_device_t sl82c105_chipset __devinitdata = { + .name = "W82C105", + .init_chipset = init_chipset_sl82c105, + .init_hwif = init_hwif_sl82c105, + .init_dma = init_dma_sl82c105, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, + .bootable = ON_BOARD, +}; + static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &sl82c105_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &sl82c105_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/sl82c105.h linux-2.6.7/drivers/ide/pci/sl82c105.h --- linux-2.6.7-rc3/drivers/ide/pci/sl82c105.h 2004-06-15 23:10:00.910902367 -0700 +++ linux-2.6.7/drivers/ide/pci/sl82c105.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,25 +0,0 @@ -#ifndef W82C105_H -#define W82C105_H - -#include -#include -#include - -static unsigned int init_chipset_sl82c105(struct pci_dev *, const char *); -static void init_hwif_sl82c105(ide_hwif_t *); -static void init_dma_sl82c105(ide_hwif_t *, unsigned long); - -static ide_pci_device_t sl82c105_chipsets[] __devinitdata = { - { /* 0 */ - .name = "W82C105", - .init_chipset = init_chipset_sl82c105, - .init_hwif = init_hwif_sl82c105, - .init_dma = init_dma_sl82c105, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, - .bootable = ON_BOARD, - } -}; - -#endif /* W82C105_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/slc90e66.c linux-2.6.7/drivers/ide/pci/slc90e66.c --- linux-2.6.7-rc3/drivers/ide/pci/slc90e66.c 2004-06-15 23:10:00.910902367 -0700 +++ linux-2.6.7/drivers/ide/pci/slc90e66.c 2004-06-15 23:10:27.777033312 -0700 @@ -21,7 +21,7 @@ #include -#include "slc90e66.h" +#define DISPLAY_SLC90E66_TIMINGS #if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) #include @@ -364,9 +364,19 @@ #endif /* !CONFIG_BLK_DEV_IDEDMA */ } +static ide_pci_device_t slc90e66_chipset __devinitdata = { + .name = "SLC90E66", + .init_chipset = init_chipset_slc90e66, + .init_hwif = init_hwif_slc90e66, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, + .bootable = ON_BOARD, +}; + static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &slc90e66_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &slc90e66_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/slc90e66.h linux-2.6.7/drivers/ide/pci/slc90e66.h --- linux-2.6.7-rc3/drivers/ide/pci/slc90e66.h 2004-06-15 23:10:00.910902367 -0700 +++ linux-2.6.7/drivers/ide/pci/slc90e66.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,27 +0,0 @@ -#ifndef SLC90E66_H -#define SLC90E66_H - -#include -#include -#include - -#define DISPLAY_SLC90E66_TIMINGS - -#define SLC90E66_DEBUG_DRIVE_INFO 0 - -static unsigned int init_chipset_slc90e66(struct pci_dev *, const char *); -static void init_hwif_slc90e66(ide_hwif_t *); - -static ide_pci_device_t slc90e66_chipsets[] __devinitdata = { - { /* 0 */ - .name = "SLC90E66", - .init_chipset = init_chipset_slc90e66, - .init_hwif = init_hwif_slc90e66, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, - .bootable = ON_BOARD, - } -}; - -#endif /* SLC90E66_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/triflex.c linux-2.6.7/drivers/ide/pci/triflex.c --- linux-2.6.7-rc3/drivers/ide/pci/triflex.c 2004-06-15 23:10:00.910902367 -0700 +++ linux-2.6.7/drivers/ide/pci/triflex.c 2004-06-15 23:10:27.779033396 -0700 @@ -41,8 +41,6 @@ #include #include -#include "triflex.h" - static struct pci_dev *triflex_dev; #ifdef CONFIG_PROC_FS @@ -217,15 +215,32 @@ return 0; } +static ide_pci_device_t triflex_device __devinitdata = { + .name = "TRIFLEX", + .init_chipset = init_chipset_triflex, + .init_hwif = init_hwif_triflex, + .channels = 2, + .autodma = AUTODMA, + .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, + .bootable = ON_BOARD, +}; + static int __devinit triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &triflex_devices[id->driver_data]); + ide_setup_pci_device(dev, &triflex_device); triflex_dev = dev; return 0; } +static struct pci_device_id triflex_pci_tbl[] = { + { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); + static struct pci_driver driver = { .name = "TRIFLEX IDE", .id_table = triflex_pci_tbl, diff -urN linux-2.6.7-rc3/drivers/ide/pci/triflex.h linux-2.6.7/drivers/ide/pci/triflex.h --- linux-2.6.7-rc3/drivers/ide/pci/triflex.h 2004-06-15 23:10:00.911902409 -0700 +++ linux-2.6.7/drivers/ide/pci/triflex.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,37 +0,0 @@ -/* - * triflex.h - * - * Copyright (C) 2002 Hewlett-Packard Development Group, L.P. - * Author: Torben Mathiasen - * - */ -#ifndef TRIFLEX_H -#define TRIFLEX_H - -#include -#include -#include - -static unsigned int __devinit init_chipset_triflex(struct pci_dev *, const char *); -static void init_hwif_triflex(ide_hwif_t *); - -static ide_pci_device_t triflex_devices[] __devinitdata = { - { - .name = "TRIFLEX", - .init_chipset = init_chipset_triflex, - .init_hwif = init_hwif_triflex, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, - .bootable = ON_BOARD, - } -}; - -static struct pci_device_id triflex_pci_tbl[] = { - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); - -#endif /* TRIFLEX_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/trm290.c linux-2.6.7/drivers/ide/pci/trm290.c --- linux-2.6.7-rc3/drivers/ide/pci/trm290.c 2004-06-15 23:10:00.911902409 -0700 +++ linux-2.6.7/drivers/ide/pci/trm290.c 2004-06-15 23:10:27.781033481 -0700 @@ -140,8 +140,6 @@ #include -#include "trm290.h" - static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) { ide_hwif_t *hwif = HWIF(drive); @@ -302,7 +300,7 @@ /* * Invoked from ide-dma.c at boot time. */ -void __init init_hwif_trm290 (ide_hwif_t *hwif) +void __devinit init_hwif_trm290(ide_hwif_t *hwif) { unsigned int cfgbase = 0; unsigned long flags; @@ -395,9 +393,17 @@ #endif } +static ide_pci_device_t trm290_chipset __devinitdata = { + .name = "TRM290", + .init_hwif = init_hwif_trm290, + .channels = 2, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, +}; + static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &trm290_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &trm290_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/trm290.h linux-2.6.7/drivers/ide/pci/trm290.h --- linux-2.6.7-rc3/drivers/ide/pci/trm290.h 2004-06-15 23:10:00.911902409 -0700 +++ linux-2.6.7/drivers/ide/pci/trm290.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,20 +0,0 @@ -#ifndef TRM290_H -#define TRM290_H - -#include -#include -#include - -extern void init_hwif_trm290(ide_hwif_t *); - -static ide_pci_device_t trm290_chipsets[] __devinitdata = { - { /* 0 */ - .name = "TRM290", - .init_hwif = init_hwif_trm290, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - } -}; - -#endif /* TRM290_H */ diff -urN linux-2.6.7-rc3/drivers/ide/pci/via82cxxx.c linux-2.6.7/drivers/ide/pci/via82cxxx.c --- linux-2.6.7-rc3/drivers/ide/pci/via82cxxx.c 2004-06-15 23:10:00.912902451 -0700 +++ linux-2.6.7/drivers/ide/pci/via82cxxx.c 2004-06-15 23:10:27.783033565 -0700 @@ -37,7 +37,8 @@ #include #include "ide-timing.h" -#include "via82cxxx.h" + +#define DISPLAY_VIA_TIMINGS #define VIA_IDE_ENABLE 0x40 #define VIA_IDE_CONFIG 0x41 @@ -607,9 +608,19 @@ hwif->drives[1].autodma = hwif->autodma; } +static ide_pci_device_t via82cxxx_chipset __devinitdata = { + .name = "VP_IDE", + .init_chipset = init_chipset_via82cxxx, + .init_hwif = init_hwif_via82cxxx, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, + .bootable = ON_BOARD, +}; + static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &via82cxxx_chipset); return 0; } diff -urN linux-2.6.7-rc3/drivers/ide/pci/via82cxxx.h linux-2.6.7/drivers/ide/pci/via82cxxx.h --- linux-2.6.7-rc3/drivers/ide/pci/via82cxxx.h 2004-06-15 23:10:00.912902451 -0700 +++ linux-2.6.7/drivers/ide/pci/via82cxxx.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,25 +0,0 @@ -#ifndef VIA82CXXX_H -#define VIA82CXXX_H - -#include -#include -#include - -#define DISPLAY_VIA_TIMINGS - -static unsigned int init_chipset_via82cxxx(struct pci_dev *, const char *); -static void init_hwif_via82cxxx(ide_hwif_t *); - -static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { - { /* 0 */ - .name = "VP_IDE", - .init_chipset = init_chipset_via82cxxx, - .init_hwif = init_hwif_via82cxxx, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .bootable = ON_BOARD, - } -}; - -#endif /* VIA82CXXX_H */ diff -urN linux-2.6.7-rc3/drivers/ieee1394/csr1212.c linux-2.6.7/drivers/ieee1394/csr1212.c --- linux-2.6.7-rc3/drivers/ieee1394/csr1212.c 2004-06-15 23:10:00.916902619 -0700 +++ linux-2.6.7/drivers/ieee1394/csr1212.c 2004-06-15 23:10:27.854036554 -0700 @@ -1061,6 +1061,10 @@ } nkv = kv->next; + if (kv->prev) + kv->prev->next = NULL; + if (kv->next) + kv->next->prev = NULL; kv->prev = NULL; kv->next = NULL; } @@ -1134,7 +1138,7 @@ /* Make sure the Extended ROM leaf is a multiple of * max_rom in size. */ leaf_size = (cache->len + (csr->max_rom - 1)) & - (csr->max_rom - 1); + ~(csr->max_rom - 1); /* Zero out the unused ROM region */ memset(cache->data + bytes_to_quads(cache->len), 0x00, diff -urN linux-2.6.7-rc3/drivers/ieee1394/csr1212.h linux-2.6.7/drivers/ieee1394/csr1212.h --- linux-2.6.7-rc3/drivers/ieee1394/csr1212.h 2004-05-09 19:32:24.000000000 -0700 +++ linux-2.6.7/drivers/ieee1394/csr1212.h 2004-06-15 23:10:27.879037607 -0700 @@ -38,9 +38,11 @@ #include #include #include +#include +#include -#define CSR1212_MALLOC(size) kmalloc((size), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -#define CSR1212_FREE(ptr) kfree(ptr) +#define CSR1212_MALLOC(size) vmalloc((size)) +#define CSR1212_FREE(ptr) vfree(ptr) #define CSR1212_BE16_TO_CPU(quad) be16_to_cpu(quad) #define CSR1212_CPU_TO_BE16(quad) cpu_to_be16(quad) #define CSR1212_BE32_TO_CPU(quad) be32_to_cpu(quad) diff -urN linux-2.6.7-rc3/drivers/ieee1394/eth1394.c linux-2.6.7/drivers/ieee1394/eth1394.c --- linux-2.6.7-rc3/drivers/ieee1394/eth1394.c 2004-06-15 23:10:00.917902661 -0700 +++ linux-2.6.7/drivers/ieee1394/eth1394.c 2004-06-15 23:10:27.912038996 -0700 @@ -89,7 +89,7 @@ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 1198 $ Ben Collins "; + "$Rev: 1224 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -1793,7 +1793,7 @@ case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 1198 $"); + strcpy (info.version, "$Rev: 1224 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff -urN linux-2.6.7-rc3/drivers/ieee1394/highlevel.c linux-2.6.7/drivers/ieee1394/highlevel.c --- linux-2.6.7-rc3/drivers/ieee1394/highlevel.c 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/drivers/ieee1394/highlevel.c 2004-06-15 23:10:28.202051206 -0700 @@ -383,7 +383,7 @@ a2sa = a2->start & align_mask; a2ea = (a2->end + alignment -1) & align_mask; - if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (end - a1ea >= size)) { + if ((a2sa - a1ea >= size) && (a2sa - start >= size) && (a2sa > start)) { as->start = max(start, a1ea); as->end = as->start + size; list_add(&as->host_list, entry); diff -urN linux-2.6.7-rc3/drivers/ieee1394/hosts.c linux-2.6.7/drivers/ieee1394/hosts.c --- linux-2.6.7-rc3/drivers/ieee1394/hosts.c 2004-06-15 23:10:00.917902661 -0700 +++ linux-2.6.7/drivers/ieee1394/hosts.c 2004-06-15 23:10:28.211051585 -0700 @@ -30,7 +30,7 @@ #include "config_roms.h" -static void delayed_reset_bus(unsigned long __reset_info) +static void delayed_reset_bus(void * __reset_info) { struct hpsb_host *host = (struct hpsb_host*)__reset_info; int generation = host->csr.generation + 1; @@ -129,9 +129,6 @@ skb_queue_head_init(&h->pending_packet_queue); INIT_LIST_HEAD(&h->addr_space); - init_timer(&h->delayed_reset); - h->delayed_reset.function = delayed_reset_bus; - h->delayed_reset.data = (unsigned long)h; for (i = 2; i < 16; i++) h->csr.gen_timestamp[i] = jiffies - 60 * HZ; @@ -140,6 +137,8 @@ atomic_set(&h->generation, 0); + INIT_WORK(&h->delayed_reset, delayed_reset_bus, h); + init_timer(&h->timeout); h->timeout.data = (unsigned long) h; h->timeout.function = abort_timedouts; @@ -188,7 +187,8 @@ { host->is_shutdown = 1; - del_timer_sync(&host->delayed_reset); + cancel_delayed_work(&host->delayed_reset); + flush_scheduled_work(); host->driver = &dummy_driver; @@ -202,7 +202,7 @@ int hpsb_update_config_rom_image(struct hpsb_host *host) { - unsigned long reset_time; + unsigned long reset_delay; int next_gen = host->csr.generation + 1; if (!host->update_config_rom) @@ -213,21 +213,21 @@ /* Stop the delayed interrupt, we're about to change the config rom and * it would be a waste to do a bus reset twice. */ - del_timer_sync(&host->delayed_reset); + cancel_delayed_work(&host->delayed_reset); /* IEEE 1394a-2000 prohibits using the same generation number * twice in a 60 second period. */ if (jiffies - host->csr.gen_timestamp[next_gen] < 60 * HZ) /* Wait 60 seconds from the last time this generation number was * used. */ - reset_time = (60 * HZ) + host->csr.gen_timestamp[next_gen]; + reset_delay = (60 * HZ) + host->csr.gen_timestamp[next_gen] - jiffies; else /* Wait 1 second in case some other code wants to change the * Config ROM in the near future. */ - reset_time = jiffies + HZ; + reset_delay = HZ; - /* This will add the timer as well as modify it */ - mod_timer(&host->delayed_reset, reset_time); + PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host); + schedule_delayed_work(&host->delayed_reset, reset_delay); return 0; } diff -urN linux-2.6.7-rc3/drivers/ieee1394/hosts.h linux-2.6.7/drivers/ieee1394/hosts.h --- linux-2.6.7-rc3/drivers/ieee1394/hosts.h 2004-05-09 19:32:02.000000000 -0700 +++ linux-2.6.7/drivers/ieee1394/hosts.h 2004-06-15 23:10:28.211051585 -0700 @@ -66,7 +66,7 @@ struct class_device class_dev; int update_config_rom; - struct timer_list delayed_reset; + struct work_struct delayed_reset; unsigned int config_roms; diff -urN linux-2.6.7-rc3/drivers/ieee1394/ieee1394_core.c linux-2.6.7/drivers/ieee1394/ieee1394_core.c --- linux-2.6.7-rc3/drivers/ieee1394/ieee1394_core.c 2004-06-15 23:10:00.919902746 -0700 +++ linux-2.6.7/drivers/ieee1394/ieee1394_core.c 2004-06-15 23:10:28.227052259 -0700 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -1033,6 +1034,11 @@ if (khpsbpkt_kill) break; + if (current->flags & PF_FREEZE) { + refrigerator(0); + continue; + } + while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { packet = (struct hpsb_packet *)skb->data; diff -urN linux-2.6.7-rc3/drivers/ieee1394/nodemgr.c linux-2.6.7/drivers/ieee1394/nodemgr.c --- linux-2.6.7-rc3/drivers/ieee1394/nodemgr.c 2004-06-15 23:10:00.920902788 -0700 +++ linux-2.6.7/drivers/ieee1394/nodemgr.c 2004-06-15 23:10:28.276054322 -0700 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "ieee1394_types.h" @@ -1474,11 +1475,20 @@ /* Sit and wait for a signal to probe the nodes on the bus. This * happens when we get a bus reset. */ - while (!down_interruptible(&hi->reset_sem) && - !down_interruptible(&nodemgr_serialize)) { + while (1) { unsigned int generation = 0; int i; + if (down_interruptible(&hi->reset_sem) || + down_interruptible(&nodemgr_serialize)) { + if (current->flags & PF_FREEZE) { + refrigerator(0); + continue; + } + printk("NodeMgr: received unexpected signal?!\n" ); + break; + } + if (hi->kill_me) break; diff -urN linux-2.6.7-rc3/drivers/ieee1394/ohci1394.c linux-2.6.7/drivers/ieee1394/ohci1394.c --- linux-2.6.7-rc3/drivers/ieee1394/ohci1394.c 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/drivers/ieee1394/ohci1394.c 2004-06-15 23:10:28.313055880 -0700 @@ -162,7 +162,7 @@ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) static char version[] __devinitdata = - "$Rev: 1203 $ Ben Collins "; + "$Rev: 1223 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -516,6 +516,12 @@ ohci->max_packet_size = 1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1); + if (ohci->max_packet_size < 512) { + HPSB_ERR("warning: Invalid max packet size of %d, setting to 512", + ohci->max_packet_size); + ohci->max_packet_size = 512; + } + /* Don't accept phy packets into AR request context */ reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); diff -urN linux-2.6.7-rc3/drivers/ieee1394/sbp2.c linux-2.6.7/drivers/ieee1394/sbp2.c --- linux-2.6.7-rc3/drivers/ieee1394/sbp2.c 2004-06-15 23:10:00.922902872 -0700 +++ linux-2.6.7/drivers/ieee1394/sbp2.c 2004-06-15 23:10:28.379058658 -0700 @@ -78,7 +78,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 1205 $ Ben Collins "; + "$Rev: 1219 $ Ben Collins "; /* * Module load parameter definitions diff -urN linux-2.6.7-rc3/drivers/ieee1394/video1394.c linux-2.6.7/drivers/ieee1394/video1394.c --- linux-2.6.7-rc3/drivers/ieee1394/video1394.c 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/drivers/ieee1394/video1394.c 2004-06-15 23:10:28.406059795 -0700 @@ -864,6 +864,7 @@ return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); + if (d == NULL) return -EFAULT; if ((v.buffer<0) || (v.buffer>d->num_desc)) { PRINT(KERN_ERR, ohci->host->id, @@ -926,6 +927,7 @@ return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); + if (d == NULL) return -EFAULT; if ((v.buffer<0) || (v.buffer>d->num_desc)) { PRINT(KERN_ERR, ohci->host->id, @@ -1009,6 +1011,7 @@ return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); + if (d == NULL) return -EFAULT; if ((v.buffer<0) || (v.buffer>d->num_desc)) { PRINT(KERN_ERR, ohci->host->id, @@ -1112,6 +1115,7 @@ return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); + if (d == NULL) return -EFAULT; if ((v.buffer<0) || (v.buffer>d->num_desc)) { PRINT(KERN_ERR, ohci->host->id, diff -urN linux-2.6.7-rc3/drivers/isdn/hisax/nj_s.c linux-2.6.7/drivers/isdn/hisax/nj_s.c --- linux-2.6.7-rc3/drivers/isdn/hisax/nj_s.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/drivers/isdn/hisax/nj_s.c 2004-06-15 23:10:28.901080636 -0700 @@ -104,9 +104,12 @@ cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); mdelay(10); - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ /* now edge triggered for TJ320 GE 13/07/00 */ /* see comment in IRQ function */ + if (cs->subtyp) /* TJ320 */ + cs->hw.njet.ctrl_reg = 0x40; /* Reset Off and status read clear */ + else + cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); mdelay(10); cs->hw.njet.auxd = 0; @@ -151,7 +154,7 @@ int __init setup_netjet_s(struct IsdnCard *card) { - int bytecnt; + int bytecnt,cfg; struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -183,6 +186,15 @@ printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n"); return(0); } + /* the TJ300 and TJ320 must be detected, the IRQ handling is different + * unfortunatly the chips use the same device ID, but the TJ320 has + * the bit20 in status PCI cfg register set + */ + pci_read_config_dword(dev_netjet, 0x04, &cfg); + if (cfg & 0x00100000) + cs->subtyp = 1; /* TJ320 */ + else + cs->subtyp = 0; /* TJ300 */ /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ if ((dev_netjet->subsystem_vendor == 0x55) && (dev_netjet->subsystem_device == 0x02)) { @@ -240,8 +252,8 @@ bytecnt = 256; printk(KERN_INFO - "NETjet-S: PCI card configured at %#lx IRQ %d\n", - cs->hw.njet.base, cs->irq); + "NETjet-S: %s card configured at %#lx IRQ %d\n", + cs->subtyp ? "TJ320" : "TJ300", cs->hw.njet.base, cs->irq); if (!request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn")) { printk(KERN_WARNING "HiSax: %s config port %#lx-%#lx already in use\n", diff -urN linux-2.6.7-rc3/drivers/isdn/i4l/isdn_common.c linux-2.6.7/drivers/isdn/i4l/isdn_common.c --- linux-2.6.7-rc3/drivers/isdn/i4l/isdn_common.c 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/drivers/isdn/i4l/isdn_common.c 2004-06-15 23:10:29.009085183 -0700 @@ -386,7 +386,7 @@ * Begin of a CAPI like LL<->HL interface, currently used only for * supplementary service (CAPI 2.0 part III) */ -#include +#include int isdn_capi_rec_hl_msg(capi_msg *cm) { diff -urN linux-2.6.7-rc3/drivers/md/raid6main.c linux-2.6.7/drivers/md/raid6main.c --- linux-2.6.7-rc3/drivers/md/raid6main.c 2004-06-15 23:10:00.975905103 -0700 +++ linux-2.6.7/drivers/md/raid6main.c 2004-06-15 23:10:29.227094362 -0700 @@ -1157,7 +1157,7 @@ * parity, or to satisfy requests * or to load a block that is being partially written. */ - if (to_read || non_overwrite || (syncing && (uptodate+failed < disks))) { + if (to_read || non_overwrite || (syncing && (uptodate < disks))) { for (i=disks; i--;) { dev = &sh->dev[i]; if (!test_bit(R5_LOCKED, &dev->flags) && !test_bit(R5_UPTODATE, &dev->flags) && diff -urN linux-2.6.7-rc3/drivers/media/dvb/frontends/tda1004x.c linux-2.6.7/drivers/media/dvb/frontends/tda1004x.c --- linux-2.6.7-rc3/drivers/media/dvb/frontends/tda1004x.c 2004-05-09 19:31:58.000000000 -0700 +++ linux-2.6.7/drivers/media/dvb/frontends/tda1004x.c 2004-06-15 23:10:29.228094404 -0700 @@ -190,6 +190,7 @@ static struct fwinfo tda10046h_fwinfo[] = { {.file_size = 286720,.fw_offset = 0x3c4f9,.fw_size = 24479} }; static int tda10046h_fwinfo_count = sizeof(tda10046h_fwinfo) / sizeof(struct fwinfo); +static int errno; static int tda1004x_write_byte(struct dvb_i2c_bus *i2c, struct tda1004x_state *tda_state, int reg, int data) diff -urN linux-2.6.7-rc3/drivers/mtd/maps/Kconfig linux-2.6.7/drivers/mtd/maps/Kconfig --- linux-2.6.7-rc3/drivers/mtd/maps/Kconfig 2004-06-15 23:10:01.019906955 -0700 +++ linux-2.6.7/drivers/mtd/maps/Kconfig 2004-06-15 23:10:29.933124087 -0700 @@ -489,5 +489,13 @@ help Map driver to support image based filesystems for uClinux. +config MTD_WRSBC8260 + tristate "Map driver for WindRiver PowerQUICC II MPC82xx board" + depends on MTD_PARTITIONS && SBC82xx + help + Map driver for WindRiver PowerQUICC II MPC82xx board. Drives + all three flash regions on CS0, CS1 and CS6 if they are configured + correctly by the boot loader. + endmenu diff -urN linux-2.6.7-rc3/drivers/mtd/maps/Makefile linux-2.6.7/drivers/mtd/maps/Makefile --- linux-2.6.7-rc3/drivers/mtd/maps/Makefile 2004-06-15 23:10:01.020906997 -0700 +++ linux-2.6.7/drivers/mtd/maps/Makefile 2004-06-15 23:10:29.943124508 -0700 @@ -56,3 +56,4 @@ obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o obj-$(CONFIG_MTD_H720X) += h720x-flash.o obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o +obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o diff -urN linux-2.6.7-rc3/drivers/mtd/maps/wr_sbc82xx_flash.c linux-2.6.7/drivers/mtd/maps/wr_sbc82xx_flash.c --- linux-2.6.7-rc3/drivers/mtd/maps/wr_sbc82xx_flash.c 1969-12-31 16:00:00.000000000 -0800 +++ linux-2.6.7/drivers/mtd/maps/wr_sbc82xx_flash.c 2004-06-15 23:10:29.979126024 -0700 @@ -0,0 +1,167 @@ +/* + * $Id: wr_sbc82xx_flash.c,v 1.1 2004/06/07 10:21:32 dwmw2 Exp $ + * + * Map for flash chips on Wind River PowerQUICC II SBC82xx board. + * + * Copyright (C) 2004 Red Hat, Inc. + * + * Author: David Woodhouse + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct mtd_info *sbcmtd[3]; +static struct mtd_partition *sbcmtd_parts[3]; + +struct map_info sbc82xx_flash_map[3] = { + {.name = "Boot flash"}, + {.name = "Alternate boot flash"}, + {.name = "User flash"} +}; + +static struct mtd_partition smallflash_parts[] = { + { + .name = "space", + .size = 0x100000, + .offset = 0, + }, { + .name = "bootloader", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static struct mtd_partition bigflash_parts[] = { + { + .name = "bootloader", + .size = 0x80000, + .offset = 0, + }, { + .name = "file system", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, + } +}; + +static const char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL}; + +int __init init_sbc82xx_flash(void) +{ + volatile memctl8260_t *mc = &immr->im_memctl; + int bigflash; + int i; + + /* First, register the boot flash, whichever we're booting from */ + if ((mc->memc_br0 & 0x00001800) == 0x00001800) { + bigflash = 0; + } else if ((mc->memc_br0 & 0x00001800) == 0x00000800) { + bigflash = 1; + } else { + printk(KERN_WARNING "Bus Controller register BR0 is %08x. Cannot determine flash configuration\n", mc->memc_br0); + return 1; + } + + /* Set parameters for the big flash chip (CS6 or CS0) */ + sbc82xx_flash_map[bigflash].buswidth = 4; + sbc82xx_flash_map[bigflash].size = 0x4000000; + + /* Set parameters for the small flash chip (CS0 or CS6) */ + sbc82xx_flash_map[!bigflash].buswidth = 1; + sbc82xx_flash_map[!bigflash].size = 0x200000; + + /* Set parameters for the user flash chip (CS1) */ + sbc82xx_flash_map[2].buswidth = 4; + sbc82xx_flash_map[2].size = 0x4000000; + + sbc82xx_flash_map[0].phys = mc->memc_br0 & 0xffff8000; + sbc82xx_flash_map[1].phys = mc->memc_br6 & 0xffff8000; + sbc82xx_flash_map[2].phys = mc->memc_br1 & 0xffff8000; + + for (i=0; i<3; i++) { + int8_t flashcs[3] = { 0, 6, 1 }; + int nr_parts; + + printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d", + sbc82xx_flash_map[i].name, sbc82xx_flash_map[i].size >> 20, flashcs[i]); + if (!sbc82xx_flash_map[i].phys) { + /* We know it can't be at zero. */ + printk("): disabled by bootloader.\n"); + continue; + } + printk(" at %08lx)\n", sbc82xx_flash_map[i].phys); + + sbc82xx_flash_map[i].virt = (unsigned long)ioremap(sbc82xx_flash_map[i].phys, sbc82xx_flash_map[i].size); + + if (!sbc82xx_flash_map[i].virt) { + printk("Failed to ioremap\n"); + continue; + } + + simple_map_init(&sbc82xx_flash_map[i]); + + sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]); + + if (!sbcmtd[i]) + continue; + + sbcmtd[i]->owner = THIS_MODULE; + + nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes, + &sbcmtd_parts[i], 0); + if (nr_parts > 0) { + add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts); + continue; + } + + /* No partitioning detected. Use default */ + if (i == 2) { + add_mtd_device(sbcmtd[i]); + } else if (i == bigflash) { + add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts)); + } else { + add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts)); + } + } + return 0; +} + +static void __exit cleanup_sbc82xx_flash(void) +{ + int i; + + for (i=0; i<3; i++) { + if (!sbcmtd[i]) + continue; + + if (i<2 || sbcmtd_parts[i]) + del_mtd_partitions(sbcmtd[i]); + else + del_mtd_device(sbcmtd[i]); + + kfree(sbcmtd_parts[i]); + map_destroy(sbcmtd[i]); + + iounmap((void *)sbc82xx_flash_map[i].virt); + sbc82xx_flash_map[i].virt = 0; + } +} + +module_init(init_sbc82xx_flash); +module_exit(cleanup_sbc82xx_flash); + + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("David Woodhouse "); +MODULE_DESCRIPTION("Flash map driver for WindRiver PowerQUICC II"); diff -urN linux-2.6.7-rc3/drivers/net/3c527.c linux-2.6.7/drivers/net/3c527.c --- linux-2.6.7-rc3/drivers/net/3c527.c 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/drivers/net/3c527.c 2004-06-15 23:10:29.981126108 -0700 @@ -287,6 +287,7 @@ } } + free_netdev(dev); return ERR_PTR(-ENODEV); } diff -urN linux-2.6.7-rc3/drivers/net/arm/am79c961a.c linux-2.6.7/drivers/net/arm/am79c961a.c --- linux-2.6.7-rc3/drivers/net/arm/am79c961a.c 2004-05-09 19:33:10.000000000 -0700 +++ linux-2.6.7/drivers/net/arm/am79c961a.c 2004-06-15 23:10:29.997126782 -0700 @@ -53,25 +53,31 @@ #ifdef __arm__ static void write_rreg(u_long base, u_int reg, u_int val) { - __asm__("str%?h %1, [%2] @ NET_RAP - str%?h %0, [%2, #-4] @ NET_RDP - " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__( + "str%?h %1, [%2] @ NET_RAP\n\t" + "str%?h %0, [%2, #-4] @ NET_RDP" + : + : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); } static inline unsigned short read_rreg(u_long base_addr, u_int reg) { unsigned short v; - __asm__("str%?h %1, [%2] @ NET_RAP - ldr%?h %0, [%2, #-4] @ NET_RDP - " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__( + "str%?h %1, [%2] @ NET_RAP\n\t" + "ldr%?h %0, [%2, #-4] @ NET_RDP" + : "=r" (v) + : "r" (reg), "r" (ISAIO_BASE + 0x0464)); return v; } static inline void write_ireg(u_long base, u_int reg, u_int val) { - __asm__("str%?h %1, [%2] @ NET_RAP - str%?h %0, [%2, #8] @ NET_IDP - " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); + __asm__( + "str%?h %1, [%2] @ NET_RAP\n\t" + "str%?h %0, [%2, #8] @ NET_IDP" + : + : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464)); } static inline unsigned short read_ireg(u_long base_addr, u_int reg) @@ -101,16 +107,16 @@ } while (length > 8) { unsigned int tmp, tmp2; - __asm__ __volatile__(" - ldm%?ia %1!, {%2, %3} - str%?h %2, [%0], #4 - mov%? %2, %2, lsr #16 - str%?h %2, [%0], #4 - str%?h %3, [%0], #4 - mov%? %3, %3, lsr #16 - str%?h %3, [%0], #4 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2) - : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldm%?ia %1!, {%2, %3}\n\t" + "str%?h %2, [%0], #4\n\t" + "mov%? %2, %2, lsr #16\n\t" + "str%?h %2, [%0], #4\n\t" + "str%?h %3, [%0], #4\n\t" + "mov%? %3, %3, lsr #16\n\t" + "str%?h %3, [%0], #4" + : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2) + : "0" (offset), "1" (buf)); length -= 8; } while (length > 0) { @@ -128,36 +134,36 @@ length = (length + 1) & ~1; if ((int)buf & 2) { unsigned int tmp; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - str%?b %2, [%1], #1 - mov%? %2, %2, lsr #8 - str%?b %2, [%1], #1 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "str%?b %2, [%1], #1\n\t" + "mov%? %2, %2, lsr #8\n\t" + "str%?b %2, [%1], #1" + : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf)); length -= 2; } while (length > 8) { unsigned int tmp, tmp2, tmp3; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - ldr%?h %3, [%0], #4 - orr%? %2, %2, %3, lsl #16 - ldr%?h %3, [%0], #4 - ldr%?h %4, [%0], #4 - orr%? %3, %3, %4, lsl #16 - stm%?ia %1!, {%2, %3} - " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3) - : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "ldr%?h %3, [%0], #4\n\t" + "orr%? %2, %2, %3, lsl #16\n\t" + "ldr%?h %3, [%0], #4\n\t" + "ldr%?h %4, [%0], #4\n\t" + "orr%? %3, %3, %4, lsl #16\n\t" + "stm%?ia %1!, {%2, %3}" + : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3) + : "0" (offset), "1" (buf)); length -= 8; } while (length > 0) { unsigned int tmp; - __asm__ __volatile__(" - ldr%?h %2, [%0], #4 - str%?b %2, [%1], #1 - mov%? %2, %2, lsr #8 - str%?b %2, [%1], #1 - " : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf)); + __asm__ __volatile__( + "ldr%?h %2, [%0], #4\n\t" + "str%?b %2, [%1], #1\n\t" + "mov%? %2, %2, lsr #8\n\t" + "str%?b %2, [%1], #1" + : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf)); length -= 2; } } @@ -618,6 +624,7 @@ if (status & CSR0_CERR) { handled = 1; mod_timer(&priv->timer, jiffies); + } } while (--n && status & (CSR0_RINT | CSR0_TINT)); return IRQ_RETVAL(handled); diff -urN linux-2.6.7-rc3/drivers/net/at1700.c linux-2.6.7/drivers/net/at1700.c --- linux-2.6.7-rc3/drivers/net/at1700.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/net/at1700.c 2004-06-15 23:10:29.998126824 -0700 @@ -242,7 +242,7 @@ { #ifdef CONFIG_MCA struct net_local *lp = netdev_priv(dev); - if (lp->mca_slot) + if (lp->mca_slot >= 0) mca_mark_as_unused(lp->mca_slot); #endif free_irq(dev->irq, NULL); @@ -444,11 +444,11 @@ break; } if (i == 8) { - goto err_out; + goto err_mca; } } else { if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr) - goto err_out; + goto err_mca; irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03]; } } @@ -546,11 +546,16 @@ if (ret) { printk (" AT1700 at %#3x is unusable due to a conflict on" "IRQ %d.\n", ioaddr, irq); - goto err_out; + goto err_mca; } return 0; +err_mca: +#ifdef CONFIG_MCA + if (slot >= 0) + mca_mark_as_unused(slot); +#endif err_out: #ifndef CONFIG_X86_PC9800 release_region(ioaddr, AT1700_IO_EXTENT); diff -urN linux-2.6.7-rc3/drivers/net/e100.c linux-2.6.7/drivers/net/e100.c --- linux-2.6.7-rc3/drivers/net/e100.c 2004-06-15 23:10:01.052908344 -0700 +++ linux-2.6.7/drivers/net/e100.c 2004-06-15 23:10:30.014127498 -0700 @@ -827,8 +827,8 @@ cb->prev->command &= cpu_to_le16(~cb_s); while(nic->cb_to_send != nic->cb_to_use) { - if(unlikely((err = e100_exec_cmd(nic, nic->cuc_cmd, - nic->cb_to_send->dma_addr)))) { + if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd, + nic->cb_to_send->dma_addr))) { /* Ok, here's where things get sticky. It's * possible that we can't schedule the command * because the controller is too busy, so @@ -1323,7 +1323,7 @@ static void e100_clean_cbs(struct nic *nic) { if(nic->cbs) { - while(nic->cb_to_clean != nic->cb_to_use) { + while(nic->cbs_avail != nic->params.cbs.count) { struct cb *cb = nic->cb_to_clean; if(cb->skb) { pci_unmap_single(nic->pdev, @@ -1333,8 +1333,8 @@ dev_kfree_skb(cb->skb); } nic->cb_to_clean = nic->cb_to_clean->next; + nic->cbs_avail++; } - nic->cbs_avail = nic->params.cbs.count; pci_free_consistent(nic->pdev, sizeof(struct cb) * nic->params.cbs.count, nic->cbs, nic->cbs_dma_addr); @@ -1659,17 +1659,16 @@ goto err_clean_cbs; e100_set_multicast_list(nic->netdev); e100_start_receiver(nic); - netif_start_queue(nic->netdev); mod_timer(&nic->watchdog, jiffies); if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, nic->netdev->name, nic->netdev))) goto err_no_irq; e100_enable_irq(nic); + netif_wake_queue(nic->netdev); return 0; err_no_irq: del_timer_sync(&nic->watchdog); - netif_stop_queue(nic->netdev); err_clean_cbs: e100_clean_cbs(nic); err_rx_clean_list: diff -urN linux-2.6.7-rc3/drivers/net/e1000/e1000_main.c linux-2.6.7/drivers/net/e1000/e1000_main.c --- linux-2.6.7-rc3/drivers/net/e1000/e1000_main.c 2004-06-15 23:10:01.064908849 -0700 +++ linux-2.6.7/drivers/net/e1000/e1000_main.c 2004-06-15 23:10:30.026128003 -0700 @@ -52,7 +52,7 @@ char e1000_driver_name[] = "e1000"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "5.2.52-k2"; +char e1000_driver_version[] = "5.2.52-k4"; char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table @@ -2143,6 +2143,7 @@ if(work_done < work_to_do || !netif_running(netdev)) { netif_rx_complete(netdev); e1000_irq_enable(adapter); + return 0; } return (work_done >= work_to_do); diff -urN linux-2.6.7-rc3/drivers/net/epic100.c linux-2.6.7/drivers/net/epic100.c --- linux-2.6.7-rc3/drivers/net/epic100.c 2004-06-15 23:10:01.068909017 -0700 +++ linux-2.6.7/drivers/net/epic100.c 2004-06-15 23:10:30.030128171 -0700 @@ -66,12 +66,15 @@ LK1.1.14 (Kryzsztof Halasa): * fix spurious bad initializations * pound phy a la SMSC's app note on the subject + + AC1.1.14ac + * fix power up/down for ethtool that broke in 1.11 */ #define DRV_NAME "epic100" -#define DRV_VERSION "1.11+LK1.1.14" -#define DRV_RELDATE "Aug 4, 2002" +#define DRV_VERSION "1.11+LK1.1.14+AC1.1.14" +#define DRV_RELDATE "June 2, 2004" /* The user-configurable values. These may be modified when a driver module is loaded.*/ @@ -1424,6 +1427,27 @@ debug = value; } +static int ethtool_begin(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + /* power-up, if interface is down */ + if (! netif_running(dev)) { + outl(0x0200, ioaddr + GENCTL); + outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); + } + return 0; +} + +static void ethtool_complete(struct net_device *dev) +{ + unsigned long ioaddr = dev->base_addr; + /* power-down, if interface is down */ + if (! netif_running(dev)) { + outl(0x0008, ioaddr + GENCTL); + outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL); + } +} + static struct ethtool_ops netdev_ethtool_ops = { .get_drvinfo = netdev_get_drvinfo, .get_settings = netdev_get_settings, @@ -1434,6 +1458,8 @@ .set_msglevel = netdev_set_msglevel, .get_sg = ethtool_op_get_sg, .get_tx_csum = ethtool_op_get_tx_csum, + .begin = ethtool_begin, + .complete = ethtool_complete }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) diff -urN linux-2.6.7-rc3/drivers/net/ibmveth.c linux-2.6.7/drivers/net/ibmveth.c --- linux-2.6.7-rc3/drivers/net/ibmveth.c 2004-06-15 23:10:01.092910028 -0700 +++ linux-2.6.7/drivers/net/ibmveth.c 2004-06-15 23:10:30.073129982 -0700 @@ -901,7 +901,7 @@ adapter = netdev->priv; memset(adapter, 0, sizeof(adapter)); - dev->driver_data = netdev; + dev->dev.driver_data = netdev; adapter->vdev = dev; adapter->netdev = netdev; @@ -971,7 +971,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) { - struct net_device *netdev = dev->driver_data; + struct net_device *netdev = dev->dev.driver_data; struct ibmveth_adapter *adapter = netdev->priv; unregister_netdev(netdev); diff -urN linux-2.6.7-rc3/drivers/net/tg3.c linux-2.6.7/drivers/net/tg3.c --- linux-2.6.7-rc3/drivers/net/tg3.c 2004-06-15 23:10:01.177913605 -0700 +++ linux-2.6.7/drivers/net/tg3.c 2004-06-15 23:10:30.163133771 -0700 @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.5" -#define DRV_MODULE_RELDATE "May 25, 2004" +#define DRV_MODULE_VERSION "3.6" +#define DRV_MODULE_RELDATE "June 12, 2004" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -177,6 +177,8 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5788, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5789, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5901_2, @@ -195,6 +197,10 @@ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5750M, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751M, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5751F, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX, @@ -7536,6 +7542,14 @@ udelay(50); tg3_nvram_init(tp); + /* Always use host TXDs, it performs better in particular + * with multi-frag packets. The tests below are kept here + * as documentation should we change this decision again + * in the future. + */ + tp->tg3_flags |= TG3_FLAG_HOST_TXDS; + +#if 0 /* Determine if TX descriptors will reside in * main memory or in the chip SRAM. */ @@ -7543,6 +7557,7 @@ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) tp->tg3_flags |= TG3_FLAG_HOST_TXDS; +#endif grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; @@ -7565,7 +7580,9 @@ tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901 || tp->pdev->device == PCI_DEVICE_ID_TIGON3_5901_2 || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F))) + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) || + (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F)) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; err = tg3_phy_probe(tp); @@ -8446,6 +8463,8 @@ if (!netif_running(dev)) return 0; + pci_restore_state(tp->pdev, tp->pci_cfg_state); + err = tg3_set_power_state(tp, 0); if (err) return err; diff -urN linux-2.6.7-rc3/drivers/net/tulip/interrupt.c linux-2.6.7/drivers/net/tulip/interrupt.c --- linux-2.6.7-rc3/drivers/net/tulip/interrupt.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/drivers/net/tulip/interrupt.c 2004-06-15 23:10:30.177134361 -0700 @@ -133,6 +133,10 @@ tp->rx_ring[entry].status); do { + if (inl(dev->base_addr + CSR5) == 0xffffffff) { + printk(KERN_DEBUG " In tulip_poll(), hardware disappeared.\n"); + break; + } /* Acknowledge current RX interrupt sources. */ outl((RxIntr | RxNoBuf), dev->base_addr + CSR5); diff -urN linux-2.6.7-rc3/drivers/pci/pci.ids linux-2.6.7/drivers/pci/pci.ids --- linux-2.6.7-rc3/drivers/pci/pci.ids 2004-06-15 23:10:01.347920761 -0700 +++ linux-2.6.7/drivers/pci/pci.ids 2004-06-15 23:10:30.662154781 -0700 @@ -6248,10 +6248,13 @@ 1676 NetXtreme BCM5750 Gigabit Ethernet 1677 NetXtreme BCM5751 Gigabit Ethernet 167c NetXtreme BCM5750M Gigabit Ethernet + 167d NetXtreme BCM5751M Gigabit Ethernet + 167e NetXtreme BCM5751F Gigabit Ethernet 1696 NetXtreme BCM5782 Gigabit Ethernet 103c 12bc HP d530 CMT (DG746A) 14e4 000d NetXtreme BCM5782 1000Base-T 169c NetXtreme BCM5788 Gigabit Ethernet + 169d NetXtreme BCM5789 Gigabit Ethernet 16a6 NetXtreme BCM5702X Gigabit Ethernet 0e11 00bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 1028 0126 BCM5702 1000Base-T diff -urN linux-2.6.7-rc3/drivers/pcmcia/yenta_socket.c linux-2.6.7/drivers/pcmcia/yenta_socket.c --- linux-2.6.7-rc3/drivers/pcmcia/yenta_socket.c 2004-05-09 19:32:39.000000000 -0700 +++ linux-2.6.7/drivers/pcmcia/yenta_socket.c 2004-06-15 23:10:30.739158023 -0700 @@ -1078,6 +1078,7 @@ CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1451A, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1510, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, TI12XX), + CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1620, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4410, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4450, TI12XX), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_4451, TI12XX), diff -urN linux-2.6.7-rc3/drivers/s390/block/dasd_cmb.c linux-2.6.7/drivers/s390/block/dasd_cmb.c --- linux-2.6.7-rc3/drivers/s390/block/dasd_cmb.c 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/drivers/s390/block/dasd_cmb.c 2004-06-15 23:10:30.803160718 -0700 @@ -58,7 +58,7 @@ dasd_ioctl_readall_cmb(struct block_device *bdev, int no, long args) { struct dasd_device *device; - struct cmbdata * __user udata; + struct cmbdata __user *udata; struct cmbdata data; size_t size; int ret; @@ -66,7 +66,7 @@ device = bdev->bd_disk->private_data; if (!device) return -EINVAL; - udata = (void *) args; + udata = (void __user *) args; size = _IOC_SIZE(no); if (!access_ok(VERIFY_WRITE, udata, size)) diff -urN linux-2.6.7-rc3/drivers/s390/block/dasd_eckd.c linux-2.6.7/drivers/s390/block/dasd_eckd.c --- linux-2.6.7-rc3/drivers/s390/block/dasd_eckd.c 2004-06-15 23:10:01.381922192 -0700 +++ linux-2.6.7/drivers/s390/block/dasd_eckd.c 2004-06-15 23:10:30.805160802 -0700 @@ -1289,7 +1289,7 @@ /* Prepare for Read Subsystem Data */ prssdp = (struct dasd_psf_prssd_data *) cqr->data; stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); - rc = copy_to_user((long *) args, (long *) stats, + rc = copy_to_user((long __user *) args, (long *) stats, sizeof(struct dasd_rssd_perf_stats_t)); } dasd_sfree_request(cqr, cqr->device); @@ -1319,10 +1319,10 @@ private = (struct dasd_eckd_private *) device->private; attrib = private->attrib; - - rc = copy_to_user((long *) args, (long *) &attrib, + + rc = copy_to_user((long __user *) args, (long *) &attrib, sizeof (struct attrib_data_t)); - + return rc; } @@ -1346,7 +1346,7 @@ if (device == NULL) return -ENODEV; - if (copy_from_user(&attrib, (void *) args, + if (copy_from_user(&attrib, (void __user *) args, sizeof (struct attrib_data_t))) { return -EFAULT; } diff -urN linux-2.6.7-rc3/drivers/s390/block/dasd_ioctl.c linux-2.6.7/drivers/s390/block/dasd_ioctl.c --- linux-2.6.7-rc3/drivers/s390/block/dasd_ioctl.c 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/drivers/s390/block/dasd_ioctl.c 2004-06-15 23:10:30.807160886 -0700 @@ -120,7 +120,7 @@ dasd_ioctl_api_version(struct block_device *bdev, int no, long args) { int ver = DASD_API_VERSION; - return put_user(ver, (int *) args); + return put_user(ver, (int __user *) args); } /* @@ -305,7 +305,7 @@ return -ENODEV; if (test_bit(DASD_FLAG_RO, &device->flags)) return -EROFS; - if (copy_from_user(&fdata, (void *) args, + if (copy_from_user(&fdata, (void __user *) args, sizeof (struct format_data_t))) return -EFAULT; if (bdev != bdev->bd_contains) { @@ -348,7 +348,7 @@ if (device == NULL) return -ENODEV; - if (copy_to_user((long *) args, (long *) &device->profile, + if (copy_to_user((long __user *) args, (long *) &device->profile, sizeof (struct dasd_profile_info_t))) return -EFAULT; return 0; @@ -441,9 +441,9 @@ spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); } - + rc = 0; - if (copy_to_user((long *) args, (long *) dasd_info, + if (copy_to_user((long __user *) args, (long *) dasd_info, ((no == (unsigned int) BIODASDINFO2) ? sizeof (struct dasd_information2_t) : sizeof (struct dasd_information_t)))) @@ -466,7 +466,7 @@ if (bdev != bdev->bd_contains) // ro setting is not allowed for partitions return -EINVAL; - if (get_user(intval, (int *) args)) + if (get_user(intval, (int __user *) args)) return -EFAULT; device = bdev->bd_disk->private_data; if (device == NULL) @@ -499,7 +499,7 @@ geo = (struct hd_geometry) {}; device->discipline->fill_geometry(device, &geo); geo.start = get_start_sect(bdev) >> device->s2b_shift; - if (copy_to_user((struct hd_geometry *) args, &geo, + if (copy_to_user((struct hd_geometry __user *) args, &geo, sizeof (struct hd_geometry))) return -EFAULT; diff -urN linux-2.6.7-rc3/drivers/s390/block/dasd_proc.c linux-2.6.7/drivers/s390/block/dasd_proc.c --- linux-2.6.7-rc3/drivers/s390/block/dasd_proc.c 2004-05-09 19:32:02.000000000 -0700 +++ linux-2.6.7/drivers/s390/block/dasd_proc.c 2004-06-15 23:10:30.807160886 -0700 @@ -30,7 +30,7 @@ static struct proc_dir_entry *dasd_statistics_entry = NULL; static inline char * -dasd_get_user_string(const char *user_buf, size_t user_len) +dasd_get_user_string(const char __user *user_buf, size_t user_len) { char *buffer; @@ -239,7 +239,7 @@ } static int -dasd_statistics_write(struct file *file, const char *user_buf, +dasd_statistics_write(struct file *file, const char __user *user_buf, unsigned long user_len, void *data) { #ifdef CONFIG_DASD_PROFILE diff -urN linux-2.6.7-rc3/drivers/s390/block/xpram.c linux-2.6.7/drivers/s390/block/xpram.c --- linux-2.6.7-rc3/drivers/s390/block/xpram.c 2004-06-15 23:10:01.384922318 -0700 +++ linux-2.6.7/drivers/s390/block/xpram.c 2004-06-15 23:10:30.809160971 -0700 @@ -155,7 +155,7 @@ { int cc; - __asm__ __volatile( + __asm__ __volatile__ ( " lhi %0,2\n" /* return unused cc 2 if pgin traps */ " .insn rre,0xb22e0000,%1,%2\n" /* pgin %1,%2 */ "0: ipm %0\n" @@ -203,7 +203,7 @@ { int cc; - __asm__ __volatile( + __asm__ __volatile__ ( " lhi %0,2\n" /* return unused cc 2 if pgout traps */ " .insn rre,0xb22f0000,%1,%2\n" /* pgout %1,%2 */ "0: ipm %0\n" @@ -332,16 +332,16 @@ static int xpram_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - struct hd_geometry *geo; + struct hd_geometry __user *geo; unsigned long size; - if (cmd != HDIO_GETGEO) + if (cmd != HDIO_GETGEO) return -EINVAL; /* * get geometry: we have to fake one... trim the size to a * multiple of 64 (32k): tell we have 16 sectors, 4 heads, * whatever cylinders. Tell also that data starts at sector. 4. */ - geo = (struct hd_geometry *) arg; + geo = (struct hd_geometry __user *) arg; size = (xpram_pages * 8) & ~0x3f; put_user(size >> 6, &geo->cylinders); put_user(4, &geo->heads); @@ -423,7 +423,7 @@ return 0; } -static struct request_queue xpram_queue; +static struct request_queue *xpram_queue; static int __init xpram_setup_blkdev(void) { @@ -450,8 +450,13 @@ * Assign the other needed values: make request function, sizes and * hardsect size. All the minor devices feature the same value. */ - blk_queue_make_request(&xpram_queue, xpram_make_request); - blk_queue_hardsect_size(&xpram_queue, 4096); + xpram_queue = blk_alloc_queue(GFP_KERNEL); + if (!xpram_queue) { + rc = -ENOMEM; + goto out_unreg; + } + blk_queue_make_request(xpram_queue, xpram_make_request); + blk_queue_hardsect_size(xpram_queue, 4096); /* * Setup device structures. @@ -467,7 +472,7 @@ disk->first_minor = i; disk->fops = &xpram_devops; disk->private_data = &xpram_devices[i]; - disk->queue = &xpram_queue; + disk->queue = xpram_queue; sprintf(disk->disk_name, "slram%d", i); sprintf(disk->devfs_name, "slram/%d", i); set_capacity(disk, xpram_sizes[i] << 1); @@ -475,6 +480,9 @@ } return 0; +out_unreg: + devfs_remove("slram"); + unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); out: while (i--) put_disk(xpram_disks[i]); @@ -493,6 +501,7 @@ } unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); devfs_remove("slram"); + blk_cleanup_queue(xpram_queue); sysdev_unregister(&xpram_sys_device); sysdev_class_unregister(&xpram_sysclass); } diff -urN linux-2.6.7-rc3/drivers/s390/char/con3215.c linux-2.6.7/drivers/s390/char/con3215.c --- linux-2.6.7-rc3/drivers/s390/char/con3215.c 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/con3215.c 2004-06-15 23:10:30.810161013 -0700 @@ -1002,7 +1002,8 @@ ret = 0; while (count > 0) { length = count < 80 ? count : 80; - length -= copy_from_user(raw->ubuffer, buf, length); + length -= copy_from_user(raw->ubuffer, + (const unsigned char __user *)buf, length); if (length == 0) { if (!ret) ret = -EFAULT; diff -urN linux-2.6.7-rc3/drivers/s390/char/keyboard.c linux-2.6.7/drivers/s390/char/keyboard.c --- linux-2.6.7-rc3/drivers/s390/char/keyboard.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/keyboard.c 2004-06-15 23:10:30.811161055 -0700 @@ -338,7 +338,7 @@ * Ioctl stuff. */ static int -do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry *user_kbe, +do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe, int cmd, int perm) { struct kbentry tmp; @@ -410,7 +410,7 @@ } static int -do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry *u_kbs, +do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs, int cmd, int perm) { unsigned char kb_func; @@ -464,9 +464,12 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { - struct kbdiacrs *a; + struct kbdiacrs __user *a; + void __user *argp; int ct, perm; + argp = (void __user *)arg; + /* * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. @@ -474,15 +477,15 @@ perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG); switch (cmd) { case KDGKBTYPE: - return put_user(KB_101, (char*) arg); + return put_user(KB_101, (char __user *)argp); case KDGKBENT: case KDSKBENT: - return do_kdsk_ioctl(kbd, (struct kbentry *)arg, cmd, perm); + return do_kdsk_ioctl(kbd, argp, cmd, perm); case KDGKBSENT: case KDSKBSENT: - return do_kdgkb_ioctl(kbd, (struct kbsentry *)arg, cmd, perm); + return do_kdgkb_ioctl(kbd, argp, cmd, perm); case KDGKBDIACR: - a = (struct kbdiacrs *) arg; + a = argp; if (put_user(kbd->accent_table_size, &a->kb_cnt)) return -EFAULT; @@ -492,7 +495,7 @@ return -EFAULT; return 0; case KDSKBDIACR: - a = (struct kbdiacrs *) arg; + a = argp; if (!perm) return -EPERM; if (get_user(ct, &a->kb_cnt)) diff -urN linux-2.6.7-rc3/drivers/s390/char/sclp_tty.c linux-2.6.7/drivers/s390/char/sclp_tty.c --- linux-2.6.7-rc3/drivers/s390/char/sclp_tty.c 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/sclp_tty.c 2004-06-15 23:10:30.813161139 -0700 @@ -112,46 +112,46 @@ switch (cmd) { case TIOCSCLPSHTAB: /* set width of horizontal tab */ - if (get_user(sclp_ioctls.htab, (unsigned short *) arg)) + if (get_user(sclp_ioctls.htab, (unsigned short __user *) arg)) rc = -EFAULT; else check = 1; break; case TIOCSCLPGHTAB: /* get width of horizontal tab */ - if (put_user(sclp_ioctls.htab, (unsigned short *) arg)) + if (put_user(sclp_ioctls.htab, (unsigned short __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSECHO: /* enable/disable echo of input */ - if (get_user(sclp_ioctls.echo, (unsigned char *) arg)) + if (get_user(sclp_ioctls.echo, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPGECHO: /* Is echo of input enabled ? */ - if (put_user(sclp_ioctls.echo, (unsigned char *) arg)) + if (put_user(sclp_ioctls.echo, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSCOLS: /* set number of columns for output */ - if (get_user(sclp_ioctls.columns, (unsigned short *) arg)) + if (get_user(sclp_ioctls.columns, (unsigned short __user *) arg)) rc = -EFAULT; else check = 1; break; case TIOCSCLPGCOLS: /* get number of columns for output */ - if (put_user(sclp_ioctls.columns, (unsigned short *) arg)) + if (put_user(sclp_ioctls.columns, (unsigned short __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSNL: /* enable/disable writing without final new line character */ - if (get_user(sclp_ioctls.final_nl, (signed char *) arg)) + if (get_user(sclp_ioctls.final_nl, (signed char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPGNL: /* Is writing without final new line character enabled ? */ - if (put_user(sclp_ioctls.final_nl, (signed char *) arg)) + if (put_user(sclp_ioctls.final_nl, (signed char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSOBUF: @@ -160,7 +160,7 @@ * up to next 4kB boundary and stored as number of SCCBs * (4kB Buffers) limitation: 256 x 4kB */ - if (get_user(obuf, (unsigned int *) arg) == 0) { + if (get_user(obuf, (unsigned int __user *) arg) == 0) { if (obuf & 0xFFF) sclp_ioctls.max_sccb = (obuf >> 12) + 1; else @@ -171,22 +171,22 @@ case TIOCSCLPGOBUF: /* get the maximum buffers size for output */ obuf = sclp_ioctls.max_sccb << 12; - if (put_user(obuf, (unsigned int *) arg)) + if (put_user(obuf, (unsigned int __user *) arg)) rc = -EFAULT; break; case TIOCSCLPGKBUF: /* get the number of buffers got from kernel at startup */ - if (put_user(sclp_ioctls.kmem_sccb, (unsigned short *) arg)) + if (put_user(sclp_ioctls.kmem_sccb, (unsigned short __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSCASE: /* enable/disable conversion from upper to lower case */ - if (get_user(sclp_ioctls.tolower, (unsigned char *) arg)) + if (get_user(sclp_ioctls.tolower, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPGCASE: /* Is conversion from upper to lower case of input enabled? */ - if (put_user(sclp_ioctls.tolower, (unsigned char *) arg)) + if (put_user(sclp_ioctls.tolower, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSDELIM: @@ -194,7 +194,7 @@ * set special character used for separating upper and * lower case, 0x00 disables this feature */ - if (get_user(sclp_ioctls.delim, (unsigned char *) arg)) + if (get_user(sclp_ioctls.delim, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPGDELIM: @@ -202,7 +202,7 @@ * get special character used for separating upper and * lower case, 0x00 disables this feature */ - if (put_user(sclp_ioctls.delim, (unsigned char *) arg)) + if (put_user(sclp_ioctls.delim, (unsigned char __user *) arg)) rc = -EFAULT; break; case TIOCSCLPSINIT: @@ -415,7 +415,8 @@ while (count > 0) { length = count < SCLP_TTY_BUF_SIZE ? count : SCLP_TTY_BUF_SIZE; - length -= copy_from_user(sclp_tty_chars, buf, length); + length -= copy_from_user(sclp_tty_chars, + (const unsigned char __user *)buf, length); if (length == 0) { if (!ret) ret = -EFAULT; diff -urN linux-2.6.7-rc3/drivers/s390/char/sclp_vt220.c linux-2.6.7/drivers/s390/char/sclp_vt220.c --- linux-2.6.7-rc3/drivers/s390/char/sclp_vt220.c 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/sclp_vt220.c 2004-06-15 23:10:30.814161181 -0700 @@ -490,7 +490,8 @@ while (count > 0) { length = count < SCLP_VT220_BUF_SIZE ? count : SCLP_VT220_BUF_SIZE; - length -= copy_from_user(tty->driver_data, buf, length); + length -= copy_from_user(tty->driver_data, + (const unsigned char __user *)buf, length); if (length == 0) { if (!ret) return -EFAULT; diff -urN linux-2.6.7-rc3/drivers/s390/char/tape.h linux-2.6.7/drivers/s390/char/tape.h --- linux-2.6.7-rc3/drivers/s390/char/tape.h 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape.h 2004-06-15 23:10:30.814161181 -0700 @@ -32,7 +32,7 @@ #ifdef DBF_LIKE_HELL #define DBF_LH(level, str, ...) \ do { \ - debug_sprintf_event(tape_dbf_area, level, str, ## __VA_ARGS__); \ + debug_sprintf_event(TAPE_DBF_AREA, level, str, ## __VA_ARGS__); \ } while (0) #else #define DBF_LH(level, str, ...) do {} while(0) @@ -43,12 +43,12 @@ */ #define DBF_EVENT(d_level, d_str...) \ do { \ - debug_sprintf_event(tape_dbf_area, d_level, d_str); \ + debug_sprintf_event(TAPE_DBF_AREA, d_level, d_str); \ } while (0) #define DBF_EXCEPTION(d_level, d_str...) \ do { \ - debug_sprintf_exception(tape_dbf_area, d_level, d_str); \ + debug_sprintf_exception(TAPE_DBF_AREA, d_level, d_str); \ } while (0) #define TAPE_VERSION_MAJOR 2 @@ -313,7 +313,7 @@ extern void tape_med_state_set(struct tape_device *, enum tape_medium_state); /* The debug area */ -extern debug_info_t *tape_dbf_area; +extern debug_info_t *TAPE_DBF_AREA; /* functions for building ccws */ static inline struct ccw1 * diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_34xx.c linux-2.6.7/drivers/s390/char/tape_34xx.c --- linux-2.6.7-rc3/drivers/s390/char/tape_34xx.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_34xx.c 2004-06-15 23:10:30.815161223 -0700 @@ -15,11 +15,19 @@ #include #include +#define TAPE_DBF_AREA tape_34xx_dbf + #include "tape.h" #include "tape_std.h" #define PRINTK_HEADER "TAPE_34XX: " +/* + * Pointer to debug area. + */ +debug_info_t *TAPE_DBF_AREA = NULL; +EXPORT_SYMBOL(TAPE_DBF_AREA); + enum tape_34xx_type { tape_3480, tape_3490, @@ -885,7 +893,7 @@ if (cmd == TAPE390_DISPLAY) { struct display_struct disp; - if (copy_from_user(&disp, (char *) arg, sizeof(disp)) != 0) + if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0) return -EFAULT; return tape_std_display(device, &disp); @@ -1343,7 +1351,13 @@ { int rc; - DBF_EVENT(3, "34xx init: $Revision: 1.20 $\n"); + TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long)); + debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); +#ifdef DBF_LIKE_HELL + debug_set_level(TAPE_DBF_AREA, 6); +#endif + + DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n"); /* Register driver for 3480/3490 tapes. */ rc = ccw_driver_register(&tape_34xx_driver); if (rc) @@ -1357,12 +1371,14 @@ tape_34xx_exit(void) { ccw_driver_unregister(&tape_34xx_driver); + + debug_unregister(TAPE_DBF_AREA); } MODULE_DEVICE_TABLE(ccw, tape_34xx_ids); MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH"); MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape " - "device driver ($Revision: 1.20 $)"); + "device driver ($Revision: 1.21 $)"); MODULE_LICENSE("GPL"); module_init(tape_34xx_init); diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_block.c linux-2.6.7/drivers/s390/char/tape_block.c --- linux-2.6.7-rc3/drivers/s390/char/tape_block.c 2004-05-09 19:33:05.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_block.c 2004-06-15 23:10:30.816161265 -0700 @@ -19,6 +19,8 @@ #include +#define TAPE_DBF_AREA tape_core_dbf + #include "tape.h" #define PRINTK_HEADER "TAPE_BLOCK: " diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_char.c linux-2.6.7/drivers/s390/char/tape_char.c --- linux-2.6.7-rc3/drivers/s390/char/tape_char.c 2004-05-09 19:33:10.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_char.c 2004-06-15 23:10:30.816161265 -0700 @@ -18,6 +18,8 @@ #include +#define TAPE_DBF_AREA tape_core_dbf + #include "tape.h" #include "tape_std.h" #include "tape_class.h" @@ -29,8 +31,8 @@ /* * file operation structure for tape character frontend */ -static ssize_t tapechar_read(struct file *, char *, size_t, loff_t *); -static ssize_t tapechar_write(struct file *, const char *, size_t, loff_t *); +static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); static int tapechar_open(struct inode *,struct file *); static int tapechar_release(struct inode *,struct file *); static int tapechar_ioctl(struct inode *, struct file *, unsigned int, @@ -134,7 +136,7 @@ * Tape device read function */ ssize_t -tapechar_read (struct file *filp, char *data, size_t count, loff_t *ppos) +tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos) { struct tape_device *device; struct tape_request *request; @@ -208,7 +210,7 @@ * Tape device write function */ ssize_t -tapechar_write(struct file *filp, const char *data, size_t count, loff_t *ppos) +tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos) { struct tape_device *device; struct tape_request *request; @@ -389,7 +391,7 @@ if (no == MTIOCTOP) { struct mtop op; - if (copy_from_user(&op, (char *) data, sizeof(op)) != 0) + if (copy_from_user(&op, (char __user *) data, sizeof(op)) != 0) return -EFAULT; if (op.mt_count < 0) return -EINVAL; @@ -436,7 +438,7 @@ if (rc < 0) return rc; pos.mt_blkno = rc; - if (copy_to_user((char *) data, &pos, sizeof(pos)) != 0) + if (copy_to_user((char __user *) data, &pos, sizeof(pos)) != 0) return -EFAULT; return 0; } @@ -466,7 +468,7 @@ get.mt_blkno = rc; } - if (copy_to_user((char *) data, &get, sizeof(get)) != 0) + if (copy_to_user((char __user *) data, &get, sizeof(get)) != 0) return -EFAULT; return 0; diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_core.c linux-2.6.7/drivers/s390/char/tape_core.c --- linux-2.6.7-rc3/drivers/s390/char/tape_core.c 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_core.c 2004-06-15 23:10:30.817161307 -0700 @@ -20,6 +20,8 @@ #include // for variable types +#define TAPE_DBF_AREA tape_core_dbf + #include "tape.h" #include "tape_std.h" @@ -39,7 +41,8 @@ /* * Pointer to debug area. */ -debug_info_t *tape_dbf_area = NULL; +debug_info_t *TAPE_DBF_AREA = NULL; +EXPORT_SYMBOL(TAPE_DBF_AREA); /* * Printable strings for tape enumerations. @@ -1176,12 +1179,12 @@ static int tape_init (void) { - tape_dbf_area = debug_register ( "tape", 1, 2, 4*sizeof(long)); - debug_register_view(tape_dbf_area, &debug_sprintf_view); + TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long)); + debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view); #ifdef DBF_LIKE_HELL - debug_set_level(tape_dbf_area, 6); + debug_set_level(TAPE_DBF_AREA, 6); #endif - DBF_EVENT(3, "tape init: ($Revision: 1.49 $)\n"); + DBF_EVENT(3, "tape init: ($Revision: 1.50 $)\n"); tape_proc_init(); tapechar_init (); tapeblock_init (); @@ -1200,19 +1203,18 @@ tapechar_exit(); tapeblock_exit(); tape_proc_cleanup(); - debug_unregister (tape_dbf_area); + debug_unregister (TAPE_DBF_AREA); } MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and " "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)"); MODULE_DESCRIPTION("Linux on zSeries channel attached " - "tape device driver ($Revision: 1.49 $)"); + "tape device driver ($Revision: 1.50 $)"); MODULE_LICENSE("GPL"); module_init(tape_init); module_exit(tape_exit); -EXPORT_SYMBOL(tape_dbf_area); EXPORT_SYMBOL(tape_generic_remove); EXPORT_SYMBOL(tape_generic_probe); EXPORT_SYMBOL(tape_generic_online); diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_proc.c linux-2.6.7/drivers/s390/char/tape_proc.c --- linux-2.6.7-rc3/drivers/s390/char/tape_proc.c 2004-05-09 19:32:28.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_proc.c 2004-06-15 23:10:30.818161350 -0700 @@ -16,6 +16,8 @@ #include #include +#define TAPE_DBF_AREA tape_core_dbf + #include "tape.h" #define PRINTK_HEADER "TAPE_PROC: " diff -urN linux-2.6.7-rc3/drivers/s390/char/tape_std.c linux-2.6.7/drivers/s390/char/tape_std.c --- linux-2.6.7-rc3/drivers/s390/char/tape_std.c 2004-05-09 19:31:57.000000000 -0700 +++ linux-2.6.7/drivers/s390/char/tape_std.c 2004-06-15 23:10:30.818161350 -0700 @@ -22,6 +22,8 @@ #include #include +#define TAPE_DBF_AREA tape_core_dbf + #include "tape.h" #include "tape_std.h" diff -urN linux-2.6.7-rc3/drivers/s390/cio/blacklist.c linux-2.6.7/drivers/s390/cio/blacklist.c --- linux-2.6.7-rc3/drivers/s390/cio/blacklist.c 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/drivers/s390/cio/blacklist.c 2004-06-15 23:10:30.820161434 -0700 @@ -308,7 +308,7 @@ return len; } -static int cio_ignore_write (struct file *file, const char *user_buf, +static int cio_ignore_write(struct file *file, const char __user *user_buf, unsigned long user_len, void *data) { char *buf; diff -urN linux-2.6.7-rc3/drivers/s390/cio/chsc.c linux-2.6.7/drivers/s390/cio/chsc.c --- linux-2.6.7-rc3/drivers/s390/cio/chsc.c 2004-06-15 23:10:01.389922529 -0700 +++ linux-2.6.7/drivers/s390/cio/chsc.c 2004-06-15 23:10:30.821161476 -0700 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/chsc.c * S/390 common I/O routines -- channel subsystem call - * $Revision: 1.111 $ + * $Revision: 1.112 $ * * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -24,7 +24,6 @@ #include "ioasm.h" #include "chsc.h" -#define CHPID_LONGS (256 / (8 * sizeof(long))) /* 256 chpids */ static struct channel_path *chps[NR_CHPIDS]; static void *sei_page; diff -urN linux-2.6.7-rc3/drivers/s390/cio/chsc.h linux-2.6.7/drivers/s390/cio/chsc.h --- linux-2.6.7-rc3/drivers/s390/cio/chsc.h 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/drivers/s390/cio/chsc.h 2004-06-15 23:10:30.821161476 -0700 @@ -23,5 +23,4 @@ extern void s390_process_css( void ); extern void chsc_validate_chpids(struct subchannel *); extern void chpid_is_actually_online(int); -extern int is_chpid_online(int); #endif diff -urN linux-2.6.7-rc3/drivers/s390/cio/device.c linux-2.6.7/drivers/s390/cio/device.c --- linux-2.6.7-rc3/drivers/s390/cio/device.c 2004-06-15 23:10:01.392922655 -0700 +++ linux-2.6.7/drivers/s390/cio/device.c 2004-06-15 23:10:30.824161602 -0700 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/device.c * bus driver for ccw devices - * $Revision: 1.119 $ + * $Revision: 1.120 $ * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -526,7 +526,8 @@ cdev = to_ccwdev(dev); if ((cdev->private->state == DEV_STATE_DISCONNECTED) && (cdev->private->devno == devno) && - (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id, 4))) { + (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id, + BUS_ID_SIZE))) { cdev->private->state = DEV_STATE_NOT_OPER; break; } diff -urN linux-2.6.7-rc3/drivers/s390/cio/device_fsm.c linux-2.6.7/drivers/s390/cio/device_fsm.c --- linux-2.6.7-rc3/drivers/s390/cio/device_fsm.c 2004-06-15 23:10:01.393922697 -0700 +++ linux-2.6.7/drivers/s390/cio/device_fsm.c 2004-06-15 23:10:30.825161644 -0700 @@ -1071,103 +1071,103 @@ * device statemachine */ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { - [DEV_STATE_NOT_OPER] { - [DEV_EVENT_NOTOPER] ccw_device_nop, - [DEV_EVENT_INTERRUPT] ccw_device_bug, - [DEV_EVENT_TIMEOUT] ccw_device_nop, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_SENSE_PGID] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_sense_pgid_irq, - [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_SENSE_ID] { - [DEV_EVENT_NOTOPER] ccw_device_recog_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_sense_id_irq, - [DEV_EVENT_TIMEOUT] ccw_device_recog_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_OFFLINE] { - [DEV_EVENT_NOTOPER] ccw_device_offline_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_offline_irq, - [DEV_EVENT_TIMEOUT] ccw_device_nop, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_VERIFY] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_verify_irq, - [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_ONLINE] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_irq, - [DEV_EVENT_TIMEOUT] ccw_device_online_timeout, - [DEV_EVENT_VERIFY] ccw_device_online_verify, - }, - [DEV_STATE_W4SENSE] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_w4sense, - [DEV_EVENT_TIMEOUT] ccw_device_nop, - [DEV_EVENT_VERIFY] ccw_device_online_verify, - }, - [DEV_STATE_DISBAND_PGID] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_disband_irq, - [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_BOXED] { - [DEV_EVENT_NOTOPER] ccw_device_offline_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_stlck_done, - [DEV_EVENT_TIMEOUT] ccw_device_stlck_done, - [DEV_EVENT_VERIFY] ccw_device_nop, + [DEV_STATE_NOT_OPER] = { + [DEV_EVENT_NOTOPER] = ccw_device_nop, + [DEV_EVENT_INTERRUPT] = ccw_device_bug, + [DEV_EVENT_TIMEOUT] = ccw_device_nop, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_SENSE_PGID] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_SENSE_ID] = { + [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_OFFLINE] = { + [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_nop, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_VERIFY] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_ONLINE] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_online_timeout, + [DEV_EVENT_VERIFY] = ccw_device_online_verify, + }, + [DEV_STATE_W4SENSE] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_w4sense, + [DEV_EVENT_TIMEOUT] = ccw_device_nop, + [DEV_EVENT_VERIFY] = ccw_device_online_verify, + }, + [DEV_STATE_DISBAND_PGID] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_BOXED] = { + [DEV_EVENT_NOTOPER] = ccw_device_offline_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_stlck_done, + [DEV_EVENT_TIMEOUT] = ccw_device_stlck_done, + [DEV_EVENT_VERIFY] = ccw_device_nop, }, /* states to wait for i/o completion before doing something */ - [DEV_STATE_CLEAR_VERIFY] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_clear_verify, - [DEV_EVENT_TIMEOUT] ccw_device_nop, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_TIMEOUT_KILL] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_killing_irq, - [DEV_EVENT_TIMEOUT] ccw_device_killing_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, //FIXME - }, - [DEV_STATE_WAIT4IO] { - [DEV_EVENT_NOTOPER] ccw_device_online_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_wait4io_irq, - [DEV_EVENT_TIMEOUT] ccw_device_wait4io_timeout, - [DEV_EVENT_VERIFY] ccw_device_wait4io_verify, - }, - [DEV_STATE_QUIESCE] { - [DEV_EVENT_NOTOPER] ccw_device_quiesce_done, - [DEV_EVENT_INTERRUPT] ccw_device_quiesce_done, - [DEV_EVENT_TIMEOUT] ccw_device_quiesce_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, + [DEV_STATE_CLEAR_VERIFY] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_clear_verify, + [DEV_EVENT_TIMEOUT] = ccw_device_nop, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_TIMEOUT_KILL] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME + }, + [DEV_STATE_WAIT4IO] = { + [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, + [DEV_EVENT_VERIFY] = ccw_device_wait4io_verify, + }, + [DEV_STATE_QUIESCE] = { + [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done, + [DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done, + [DEV_EVENT_TIMEOUT] = ccw_device_quiesce_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, }, /* special states for devices gone not operational */ - [DEV_STATE_DISCONNECTED] { - [DEV_EVENT_NOTOPER] ccw_device_nop, - [DEV_EVENT_INTERRUPT] ccw_device_start_id, - [DEV_EVENT_TIMEOUT] ccw_device_bug, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_DISCONNECTED_SENSE_ID] { - [DEV_EVENT_NOTOPER] ccw_device_recog_notoper, - [DEV_EVENT_INTERRUPT] ccw_device_sense_id_irq, - [DEV_EVENT_TIMEOUT] ccw_device_recog_timeout, - [DEV_EVENT_VERIFY] ccw_device_nop, - }, - [DEV_STATE_CMFCHANGE] { - [DEV_EVENT_NOTOPER] ccw_device_change_cmfstate, - [DEV_EVENT_INTERRUPT] ccw_device_change_cmfstate, - [DEV_EVENT_TIMEOUT] ccw_device_change_cmfstate, - [DEV_EVENT_VERIFY] ccw_device_change_cmfstate, + [DEV_STATE_DISCONNECTED] = { + [DEV_EVENT_NOTOPER] = ccw_device_nop, + [DEV_EVENT_INTERRUPT] = ccw_device_start_id, + [DEV_EVENT_TIMEOUT] = ccw_device_bug, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_DISCONNECTED_SENSE_ID] = { + [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, + [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq, + [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout, + [DEV_EVENT_VERIFY] = ccw_device_nop, + }, + [DEV_STATE_CMFCHANGE] = { + [DEV_EVENT_NOTOPER] = ccw_device_change_cmfstate, + [DEV_EVENT_INTERRUPT] = ccw_device_change_cmfstate, + [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, + [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, }, }; diff -urN linux-2.6.7-rc3/drivers/s390/crypto/z90crypt.h linux-2.6.7/drivers/s390/crypto/z90crypt.h --- linux-2.6.7-rc3/drivers/s390/crypto/z90crypt.h 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/drivers/s390/crypto/z90crypt.h 2004-06-15 23:10:30.826161686 -0700 @@ -46,12 +46,12 @@ * - length(n_modulus) = inputdatalength */ struct ica_rsa_modexpo { - char * inputdata; + char __user * inputdata; unsigned int inputdatalength; - char * outputdata; + char __user * outputdata; unsigned int outputdatalength; - char * b_key; - char * n_modulus; + char __user * b_key; + char __user * n_modulus; }; /** @@ -69,15 +69,15 @@ * - length(u_mult_inv) = inputdatalength/2 + 8 */ struct ica_rsa_modexpo_crt { - char * inputdata; + char __user * inputdata; unsigned int inputdatalength; - char * outputdata; + char __user * outputdata; unsigned int outputdatalength; - char * bp_key; - char * bq_key; - char * np_prime; - char * nq_prime; - char * u_mult_inv; + char __user * bp_key; + char __user * bq_key; + char __user * np_prime; + char __user * nq_prime; + char __user * u_mult_inv; }; #define Z90_IOCTL_MAGIC 'z' // NOTE: Need to allocate from linux folks diff -urN linux-2.6.7-rc3/drivers/s390/crypto/z90main.c linux-2.6.7/drivers/s390/crypto/z90main.c --- linux-2.6.7-rc3/drivers/s390/crypto/z90main.c 2004-05-09 19:31:58.000000000 -0700 +++ linux-2.6.7/drivers/s390/crypto/z90main.c 2004-06-15 23:10:30.829161813 -0700 @@ -361,7 +361,7 @@ int buff_size; // size of the buffer for the request char resp_buff[RESPBUFFSIZE]; int resp_buff_size; - char * resp_addr; // address of response in user space + char __user * resp_addr; // address of response in user space unsigned int funccode; // function code of request wait_queue_head_t waitq; unsigned long requestsent; // time at which the request was sent @@ -378,8 +378,9 @@ */ static int z90crypt_open(struct inode *, struct file *); static int z90crypt_release(struct inode *, struct file *); -static ssize_t z90crypt_read(struct file *, char *, size_t, loff_t *); -static ssize_t z90crypt_write(struct file *, const char *, size_t, loff_t *); +static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t z90crypt_write(struct file *, const char __user *, + size_t, loff_t *); static int z90crypt_ioctl(struct inode *, struct file *, unsigned int, unsigned long); @@ -389,7 +390,7 @@ static void z90crypt_cleanup_task(unsigned long); static int z90crypt_status(char *, char **, off_t, int, int *, void *); -static int z90crypt_status_write(struct file *, const char *, +static int z90crypt_status_write(struct file *, const char __user *, unsigned long, void *); /** @@ -473,9 +474,9 @@ trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - struct ica_rsa_modexpo_32 *mex32u = compat_ptr(arg); + struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); struct ica_rsa_modexpo_32 mex32k; - struct ica_rsa_modexpo *mex64; + struct ica_rsa_modexpo __user *mex64; int ret = 0; unsigned int i; @@ -517,9 +518,9 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file) { - struct ica_rsa_modexpo_crt_32 *crt32u = compat_ptr(arg); + struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); struct ica_rsa_modexpo_crt_32 crt32k; - struct ica_rsa_modexpo_crt *crt64; + struct ica_rsa_modexpo_crt __user *crt64; int ret = 0; unsigned int i; @@ -841,7 +842,7 @@ * z90crypt_read will not be supported beyond z90crypt 1.3.1 */ static ssize_t -z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) +z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { PDEBUG("filp %p (PID %d)\n", filp, PID()); return -EPERM; @@ -854,7 +855,7 @@ */ #include static ssize_t -z90crypt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) +z90crypt_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { unsigned char *temp_buff; @@ -892,7 +893,7 @@ * Write is is not allowed */ static ssize_t -z90crypt_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos) +z90crypt_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { PDEBUG("filp %p (PID %d)\n", filp, PID()); return -EPERM; @@ -1258,7 +1259,7 @@ * process_results copies the user's work from kernel space. */ static inline int -z90crypt_process_results(struct work_element *we_p, char *buf) +z90crypt_process_results(struct work_element *we_p, char __user *buf) { int rv; @@ -1556,7 +1557,7 @@ static inline int z90crypt_prepare(struct work_element *we_p, unsigned int funccode, - const char *buffer) + const char __user *buffer) { int rv; @@ -1641,7 +1642,7 @@ PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid); return rv; } - if ((rv = z90crypt_prepare(we_p, cmd, (const char *)arg))) + if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg))) PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv); if (!rv) if ((rv = z90crypt_send(we_p, (const char *)arg))) @@ -1653,7 +1654,7 @@ rv = we_p->retcode; } if (!rv) - rv = z90crypt_process_results(we_p, (char *)arg); + rv = z90crypt_process_results(we_p, (char __user *)arg); if ((we_p->status[0] & STAT_FAILED)) { switch (rv) { @@ -1748,49 +1749,49 @@ case Z90STAT_TOTALCOUNT: tempstat = get_status_totalcount(); - if (copy_to_user((int *)arg, &tempstat,sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_PCICACOUNT: tempstat = get_status_PCICAcount(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_PCICCCOUNT: tempstat = get_status_PCICCcount(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_PCIXCCCOUNT: tempstat = get_status_PCIXCCcount(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_REQUESTQ_COUNT: tempstat = get_status_requestq_count(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_PENDINGQ_COUNT: tempstat = get_status_pendingq_count(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_TOTALOPEN_COUNT: tempstat = get_status_totalopen_count(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; case Z90STAT_DOMAIN_INDEX: tempstat = get_status_domain_index(); - if (copy_to_user((int *)arg, &tempstat, sizeof(int)) != 0) + if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0) ret = -EFAULT; break; @@ -1802,7 +1803,8 @@ break; } get_status_status_mask(status); - if (copy_to_user((char *) arg, status, Z90CRYPT_NUM_APS) != 0) + if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS) + != 0) ret = -EFAULT; kfree(status); break; @@ -1815,7 +1817,7 @@ break; } get_status_qdepth_mask(qdepth); - if (copy_to_user((char *) arg, qdepth, Z90CRYPT_NUM_APS) != 0) + if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0) ret = -EFAULT; kfree(qdepth); break; @@ -1828,7 +1830,7 @@ break; } get_status_perdevice_reqcnt(reqcnt); - if (copy_to_user((char *) arg, reqcnt, + if (copy_to_user((char __user *) arg, reqcnt, Z90CRYPT_NUM_APS * sizeof(int)) != 0) ret = -EFAULT; kfree(reqcnt); @@ -1861,7 +1863,7 @@ get_status_status_mask(pstat->status); get_status_qdepth_mask(pstat->qdepth); - if (copy_to_user((struct ica_z90_status *) arg, pstat, + if (copy_to_user((struct ica_z90_status __user *) arg, pstat, sizeof(struct ica_z90_status)) != 0) ret = -EFAULT; kfree(pstat); @@ -2104,7 +2106,7 @@ } static int -z90crypt_status_write(struct file *file, const char *buffer, +z90crypt_status_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { int i, j, len, offs, found, eof; @@ -2209,7 +2211,7 @@ */ static inline int receive_from_crypto_device(int index, unsigned char *psmid, int *buff_len_p, - unsigned char *buff, unsigned char **dest_p_p) + unsigned char *buff, unsigned char __user **dest_p_p) { int dv, rv; struct device *dev_ptr; @@ -2397,7 +2399,7 @@ static inline void helper_handle_work_element(int index, unsigned char psmid[8], int rc, int buff_len, unsigned char *buff, - unsigned char *resp_addr) + unsigned char __user *resp_addr) { struct work_element *pq_p; struct list_head *lptr, *tptr; @@ -2502,7 +2504,8 @@ z90crypt_reader_task(unsigned long ptr) { int workavail, remaining, index, rc, buff_len; - unsigned char psmid[8], *resp_addr; + unsigned char psmid[8]; + unsigned char __user *resp_addr; static unsigned char buff[1024]; PDEBUG("jiffies %ld\n", jiffies); diff -urN linux-2.6.7-rc3/drivers/s390/net/ctctty.c linux-2.6.7/drivers/s390/net/ctctty.c --- linux-2.6.7-rc3/drivers/s390/net/ctctty.c 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/drivers/s390/net/ctctty.c 2004-06-15 23:10:30.830161855 -0700 @@ -515,7 +515,8 @@ } skb_reserve(skb, skb_res); if (from_user) - copy_from_user(skb_put(skb, c), buf, c); + copy_from_user(skb_put(skb, c), + (const u_char __user *)buf, c); else memcpy(skb_put(skb, c), buf, c); skb_queue_tail(&info->tx_queue, skb); @@ -640,7 +641,7 @@ * allows RS485 driver to be written in user space. */ static int -ctc_tty_get_lsr_info(ctc_tty_info * info, uint * value) +ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value) { u_char status; uint result; @@ -650,7 +651,7 @@ status = info->lsr; spin_unlock_irqrestore(&ctc_tty_lock, flags); result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - put_user(result, (uint *) value); + put_user(result, value); return 0; } @@ -743,14 +744,14 @@ printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME, info->line); #endif - error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong *) arg); + error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg); return error; case TIOCSSOFTCAR: #ifdef CTC_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME, info->line); #endif - error = get_user(arg, (ulong *) arg); + error = get_user(arg, (ulong __user *) arg); if (error) return error; tty->termios->c_cflag = @@ -762,11 +763,11 @@ printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME, info->line); #endif - error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(uint)); + error = verify_area(VERIFY_WRITE, (void __user *) arg, sizeof(uint)); if (error) return error; else - return ctc_tty_get_lsr_info(info, (uint *) arg); + return ctc_tty_get_lsr_info(info, (uint __user *) arg); default: #ifdef CTC_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd, diff -urN linux-2.6.7-rc3/drivers/s390/net/qeth.h linux-2.6.7/drivers/s390/net/qeth.h --- linux-2.6.7-rc3/drivers/s390/net/qeth.h 2004-06-15 23:10:01.400922992 -0700 +++ linux-2.6.7/drivers/s390/net/qeth.h 2004-06-15 23:10:30.836162107 -0700 @@ -23,7 +23,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.109 $" +#define VERSION_QETH_H "$Revision: 1.110 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -380,11 +380,6 @@ * outbound: filled by driver; owned by hardware in order to be sent */ QETH_QDIO_BUF_PRIMED, - /* - * inbound only: an error condition has been detected for a buffer - * the buffer will be discarded (not read out) - */ - QETH_QDIO_BUF_ERROR, }; enum qeth_qdio_info_states { @@ -423,7 +418,7 @@ struct qeth_qdio_out_buffer { struct qdio_buffer *buffer; - volatile enum qeth_qdio_buffer_states state; + atomic_t state; volatile int next_element_to_fill; struct sk_buff_head skb_list; }; diff -urN linux-2.6.7-rc3/drivers/s390/net/qeth_main.c linux-2.6.7/drivers/s390/net/qeth_main.c --- linux-2.6.7-rc3/drivers/s390/net/qeth_main.c 2004-06-15 23:10:01.407923287 -0700 +++ linux-2.6.7/drivers/s390/net/qeth_main.c 2004-06-15 23:10:30.844162444 -0700 @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.118 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.121 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.118 $ $Date: 2004/06/02 06:34:52 $ + * $Revision: 1.121 $ $Date: 2004/06/11 16:32:15 $ * * 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 @@ -78,7 +78,7 @@ #include "qeth_mpc.h" #include "qeth_fs.h" -#define VERSION_QETH_C "$Revision: 1.118 $" +#define VERSION_QETH_C "$Revision: 1.121 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -2345,13 +2345,17 @@ } static inline void -qeth_clear_output_buffer(struct qeth_card *card, +qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, struct qeth_qdio_out_buffer *buf) { int i; struct sk_buff *skb; - for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){ + /* is PCI flag set on buffer? */ + if (buf->buffer->element[0].flags & 0x40) + atomic_dec(&queue->set_pci_flags_count); + + for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i){ buf->buffer->element[i].length = 0; buf->buffer->element[i].addr = NULL; buf->buffer->element[i].flags = 0; @@ -2361,7 +2365,7 @@ } } buf->next_element_to_fill = 0; - buf->state = QETH_QDIO_BUF_EMPTY; + atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY); } static inline void @@ -2578,8 +2582,17 @@ QETH_DBF_TEXT(trace, 2, "flushbuf"); QETH_DBF_TEXT_(trace, 2, " err%d", rc); queue->card->stats.tx_errors += count; + /* ok, since do_QDIO went wrong the buffers have not been given + * to the hardware. they still belong to us, so we can clear + * them and reuse then, i.e. set back next_buf_to_fill*/ + for (i = index; i < index + count; ++i) { + buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; + qeth_clear_output_buffer(queue, buf); + } + queue->next_buf_to_fill = index; return; } + atomic_add(count, &queue->used_buffers); #ifdef CONFIG_QETH_PERF_STATS queue->card->perf_stats.bufs_sent += count; #endif @@ -2617,11 +2630,11 @@ queue->do_pack = 0; /* flush packing buffers */ buffer = &queue->bufs[queue->next_buf_to_fill]; - BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED); - if (buffer->next_element_to_fill > 0) { - buffer->state = QETH_QDIO_BUF_PRIMED; + if ((atomic_read(&buffer->state) == + QETH_QDIO_BUF_EMPTY) && + (buffer->next_element_to_fill > 0)) { + atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED); flush_count++; - atomic_inc(&queue->used_buffers); queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q; @@ -2635,17 +2648,17 @@ qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue, int under_int) { struct qeth_qdio_out_buffer *buffer; + int index; - buffer = &queue->bufs[queue->next_buf_to_fill]; - BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED); - if (buffer->next_element_to_fill > 0){ + index = queue->next_buf_to_fill; + buffer = &queue->bufs[index]; + if((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) && + (buffer->next_element_to_fill > 0)){ /* it's a packing buffer */ - buffer->state = QETH_QDIO_BUF_PRIMED; - atomic_inc(&queue->used_buffers); - qeth_flush_buffers(queue, under_int, queue->next_buf_to_fill, - 1); + atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q; + qeth_flush_buffers(queue, under_int, index, 1); } } @@ -2688,13 +2701,9 @@ qeth_schedule_recovery(card); return; } - /* is PCI flag set on buffer? */ - if (buffer->buffer->element[0].flags & 0x40) - atomic_dec(&queue->set_pci_flags_count); - - qeth_clear_output_buffer(card, buffer); - atomic_dec(&queue->used_buffers); + qeth_clear_output_buffer(queue, buffer); } + atomic_sub(count, &queue->used_buffers); netif_wake_queue(card->dev); #ifdef CONFIG_QETH_PERF_STATS @@ -2887,8 +2896,8 @@ /* free outbound qdio_qs */ for (i = 0; i < card->qdio.no_out_queues; ++i){ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) - qeth_clear_output_buffer(card, &card->qdio. - out_qs[i]->bufs[j]); + qeth_clear_output_buffer(card->qdio.out_qs[i], + &card->qdio.out_qs[i]->bufs[j]); kfree(card->qdio.out_qs[i]); } kfree(card->qdio.out_qs); @@ -2905,8 +2914,8 @@ for (i = 0; i < card->qdio.no_out_queues; ++i) if (card->qdio.out_qs[i]){ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) - qeth_clear_output_buffer(card, &card->qdio. - out_qs[i]->bufs[j]); + qeth_clear_output_buffer(card->qdio.out_qs[i], + &card->qdio.out_qs[i]->bufs[j]); } } @@ -2958,8 +2967,8 @@ memset(card->qdio.out_qs[i]->qdio_bufs, 0, QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer)); for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){ - qeth_clear_output_buffer(card, &card->qdio. - out_qs[i]->bufs[j]); + qeth_clear_output_buffer(card->qdio.out_qs[i], + &card->qdio.out_qs[i]->bufs[j]); } card->qdio.out_qs[i]->card = card; card->qdio.out_qs[i]->next_buf_to_fill = 0; @@ -3671,7 +3680,7 @@ if (!queue->do_pack) { QETH_DBF_TEXT(trace, 6, "fillbfnp"); /* set state to PRIMED -> will be flushed */ - buf->state = QETH_QDIO_BUF_PRIMED; + atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); } else { QETH_DBF_TEXT(trace, 6, "fillbfpa"); #ifdef CONFIG_QETH_PERF_STATS @@ -3683,7 +3692,7 @@ * packed buffer if full -> set state PRIMED * -> will be flushed */ - buf->state = QETH_QDIO_BUF_PRIMED; + atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); } } return 0; @@ -3696,32 +3705,27 @@ { struct qeth_qdio_out_buffer *buffer; int index; - int rc = 0; QETH_DBF_TEXT(trace, 6, "dosndpfa"); spin_lock(&queue->lock); - /* do we have empty buffers? */ - if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 1)){ + index = queue->next_buf_to_fill; + buffer = &queue->bufs[queue->next_buf_to_fill]; + /* + * check if buffer is empty to make sure that we do not 'overtake' + * ourselves and try to fill a buffer that is already primed + */ + if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { card->stats.tx_dropped++; - rc = -EBUSY; spin_unlock(&queue->lock); - goto out; + return -EBUSY; } - index = queue->next_buf_to_fill; - buffer = &queue->bufs[queue->next_buf_to_fill]; - BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED); queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q; - atomic_inc(&queue->used_buffers); - spin_unlock(&queue->lock); - - /* go on sending ... */ - netif_wake_queue(skb->dev); qeth_fill_buffer(queue, buffer, (char *)hdr, skb); qeth_flush_buffers(queue, 0, index, 1); -out: - return rc; + spin_unlock(&queue->lock); + return 0; } static inline int @@ -3737,35 +3741,43 @@ QETH_DBF_TEXT(trace, 6, "dosndpkt"); spin_lock(&queue->lock); - /* do we have empty buffers? */ - if (atomic_read(&queue->used_buffers) >= (QDIO_MAX_BUFFERS_PER_Q - 2)){ - card->stats.tx_dropped++; - rc = -EBUSY; - goto out; - } start_index = queue->next_buf_to_fill; buffer = &queue->bufs[queue->next_buf_to_fill]; - BUG_ON(buffer->state == QETH_QDIO_BUF_PRIMED); + /* + * check if buffer is empty to make sure that we do not 'overtake' + * ourselves and try to fill a buffer that is already primed + */ + if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ + card->stats.tx_dropped++; + spin_unlock(&queue->lock); + return -EBUSY; + } if (queue->do_pack){ /* does packet fit in current buffer? */ - if((QETH_MAX_BUFFER_ELEMENTS(card) - buffer->next_element_to_fill) - < elements_needed){ + if((QETH_MAX_BUFFER_ELEMENTS(card) - + buffer->next_element_to_fill) < elements_needed){ /* ... no -> set state PRIMED */ - buffer->state = QETH_QDIO_BUF_PRIMED; + atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); flush_count++; - atomic_inc(&queue->used_buffers); queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q; buffer = &queue->bufs[queue->next_buf_to_fill]; + /* we did a step forward, so check buffer state again */ + if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ + card->stats.tx_dropped++; + qeth_flush_buffers(queue, 0, start_index, 1); + spin_unlock(&queue->lock); + /* return EBUSY because we sent old packet, not + * the current one */ + return -EBUSY; + } } } - qeth_fill_buffer(queue, buffer, (char *)hdr, skb); - if (buffer->state == QETH_QDIO_BUF_PRIMED){ + if (atomic_read(&buffer->state) == QETH_QDIO_BUF_PRIMED){ /* next time fill the next buffer */ flush_count++; - atomic_inc(&queue->used_buffers); queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q; } @@ -3777,9 +3789,8 @@ if (!atomic_read(&queue->set_pci_flags_count)) qeth_flush_buffers_on_no_pci(queue, 0); -out: - spin_unlock(&queue->lock); + spin_unlock(&queue->lock); return rc; } @@ -4079,21 +4090,43 @@ static int qeth_send_ipa_arp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, - int len, int (*reply_cb) - (struct qeth_card *, - struct qeth_reply*, unsigned long), + int len, int (*reply_cb)(struct qeth_card *, + struct qeth_reply *, + unsigned long), void *reply_param) { - int rc; - QETH_DBF_TEXT(trace,4,"sendarp"); memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE); memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data), &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH); - rc = qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob, - reply_cb, reply_param); - return rc; + return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob, + reply_cb, reply_param); +} + +static int +qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, + int len, int (*reply_cb)(struct qeth_card *, + struct qeth_reply *, + unsigned long), + void *reply_param) +{ + u16 s1, s2; + + QETH_DBF_TEXT(trace,4,"sendsnmp"); + + memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE); + memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data), + &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH); + /* adjust PDU length fields in IPA_PDU_HEADER */ + s1 = (u32) IPA_PDU_HEADER_SIZE + len; + s2 = (u32) len; + memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2); + memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2); + memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2); + memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2); + return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob, + reply_cb, reply_param); } static struct qeth_cmd_buffer * @@ -4136,8 +4169,7 @@ rc = qeth_send_ipa_arp_cmd(card, iob, QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN, - qeth_arp_query_cb, - (void *)&qinfo); + qeth_arp_query_cb, (void *)&qinfo); if (rc) { tmp = rc; PRINT_WARN("Error while querying ARP cache on %s: %s " @@ -4247,7 +4279,8 @@ { struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - struct qeth_snmp_ureq ureq; + struct qeth_snmp_ureq *ureq; + int req_len; struct qeth_arp_query_info qinfo = {0, }; int rc = 0; @@ -4260,29 +4293,39 @@ "on %s!\n", card->info.if_name); return -EOPNOTSUPP; } - if (copy_from_user(&ureq, udata, sizeof(struct qeth_snmp_ureq))) + /* skip 4 bytes (data_len struct member) to get req_len */ + if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int))) return -EFAULT; - qinfo.udata_len = ureq.hdr.data_len; - if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))) + ureq = kmalloc(req_len, GFP_KERNEL); + if (!ureq) { + QETH_DBF_TEXT(trace, 2, "snmpnome"); return -ENOMEM; + } + if (copy_from_user(ureq, udata, req_len)){ + kfree(ureq); + return -EFAULT; + } + qinfo.udata_len = ureq->hdr.data_len; + if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))){ + kfree(ureq); + return -ENOMEM; + } memset(qinfo.udata, 0, qinfo.udata_len); qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr); iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, - QETH_SNMP_SETADP_CMDLENGTH+ureq.hdr.req_len); + QETH_SNMP_SETADP_CMDLENGTH + req_len); cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); - memcpy(&cmd->data.setadapterparms.data.snmp, &ureq.cmd, - sizeof(struct qeth_snmp_cmd)); - rc = qeth_send_ipa_arp_cmd(card, iob, - QETH_SETADP_BASE_LEN + QETH_ARP_DATA_SIZE + - ureq.hdr.req_len, qeth_snmp_command_cb, - (void *)&qinfo); + memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); + rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, + qeth_snmp_command_cb, (void *)&qinfo); if (rc) PRINT_WARN("SNMP command failed on %s: (0x%x)\n", card->info.if_name, rc); else copy_to_user(udata, qinfo.udata, qinfo.udata_len); + kfree(ureq); kfree(qinfo.udata); return rc; } diff -urN linux-2.6.7-rc3/drivers/scsi/Kconfig linux-2.6.7/drivers/scsi/Kconfig --- linux-2.6.7-rc3/drivers/scsi/Kconfig 2004-06-15 23:10:01.428924170 -0700 +++ linux-2.6.7/drivers/scsi/Kconfig 2004-06-15 23:10:31.055171328 -0700 @@ -352,7 +352,7 @@ # All the I2O code and drivers do not seem to be 64bit safe. config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on !64BIT && SCSI + depends on !64BIT && SCSI && PCI help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained @@ -494,9 +494,15 @@ substantial, so users of MultiMaster Host Adapters may wish to omit it. +# +# This is marked broken because it uses over 4kB of stack in +# just two routines: +# 2076 CpqTsProcessIMQEntry +# 2052 PeekIMQEntry +# config SCSI_CPQFCTS tristate "Compaq Fibre Channel 64-bit/66Mhz HBA support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN help Say Y here to compile in support for the Compaq StorageWorks Fibre Channel 64-bit/66Mhz Host Bus Adapter. diff -urN linux-2.6.7-rc3/drivers/scsi/cpqfcTScontrol.c linux-2.6.7/drivers/scsi/cpqfcTScontrol.c --- linux-2.6.7-rc3/drivers/scsi/cpqfcTScontrol.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/drivers/scsi/cpqfcTScontrol.c 2004-06-15 23:10:31.592193938 -0700 @@ -607,6 +607,7 @@ if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 ) { TachFCHDR_GCMND* fchs; +#error This is too much stack ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL); @@ -718,6 +719,7 @@ ULONG x_ID; ULONG ulBuff, dwStatus; TachFCHDR_GCMND* fchs; +#error This is too much stack ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field diff -urN linux-2.6.7-rc3/drivers/scsi/ide-scsi.c linux-2.6.7/drivers/scsi/ide-scsi.c --- linux-2.6.7-rc3/drivers/scsi/ide-scsi.c 2004-06-15 23:10:01.492926864 -0700 +++ linux-2.6.7/drivers/scsi/ide-scsi.c 2004-06-15 23:10:31.811203159 -0700 @@ -318,6 +318,13 @@ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; + /* retry only "normal" I/O: */ + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { + rq->errors = 1; + ide_end_drive_cmd(drive, stat, err); + return ide_stopped; + } + if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) /* force an abort */ HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); @@ -334,6 +341,13 @@ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) return ide_stopped; + /* retry only "normal" I/O: */ + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { + rq->errors = 1; + ide_end_drive_cmd(drive, BUSY_STAT, 0); + return ide_stopped; + } + #if IDESCSI_DEBUG_LOG printk(KERN_WARNING "idescsi_atapi_abort called for %lu\n", ((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number); diff -urN linux-2.6.7-rc3/drivers/serial/8250_pnp.c linux-2.6.7/drivers/serial/8250_pnp.c --- linux-2.6.7-rc3/drivers/serial/8250_pnp.c 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/drivers/serial/8250_pnp.c 2004-06-15 23:10:34.081298738 -0700 @@ -437,7 +437,7 @@ .name = "serial", .id_table = pnp_dev_table, .probe = serial_pnp_probe, - .remove = serial_pnp_remove, + .remove = __devexit_p(serial_pnp_remove), }; static int __init serial8250_pnp_init(void) diff -urN linux-2.6.7-rc3/drivers/serial/Kconfig linux-2.6.7/drivers/serial/Kconfig --- linux-2.6.7-rc3/drivers/serial/Kconfig 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/drivers/serial/Kconfig 2004-06-15 23:10:34.082298780 -0700 @@ -259,6 +259,7 @@ config SERIAL_S3C2410_CONSOLE bool "Support for console on S3C2410 serial port" depends on SERIAL_S3C2410=y + select SERIAL_CORE_CONSOLE help Allow selection of the S3C2410 on-board serial ports for use as an virtual console. diff -urN linux-2.6.7-rc3/drivers/usb/core/devio.c linux-2.6.7/drivers/usb/core/devio.c --- linux-2.6.7-rc3/drivers/usb/core/devio.c 2004-06-15 23:10:01.818940586 -0700 +++ linux-2.6.7/drivers/usb/core/devio.c 2004-06-15 23:10:34.260306275 -0700 @@ -719,7 +719,7 @@ static int proc_resetdevice(struct dev_state *ps) { - return usb_reset_device(ps->dev); + return __usb_reset_device(ps->dev); } diff -urN linux-2.6.7-rc3/drivers/usb/media/Kconfig linux-2.6.7/drivers/usb/media/Kconfig --- linux-2.6.7-rc3/drivers/usb/media/Kconfig 2004-05-09 19:31:57.000000000 -0700 +++ linux-2.6.7/drivers/usb/media/Kconfig 2004-06-15 23:10:34.631321896 -0700 @@ -108,7 +108,7 @@ config USB_PWC tristate "USB Philips Cameras" - depends on USB && VIDEO_DEV && BROKEN + depends on USB && VIDEO_DEV ---help--- Say Y or M here if you want to use one of these Philips & OEM webcams: diff -urN linux-2.6.7-rc3/drivers/usb/media/pwc-if.c linux-2.6.7/drivers/usb/media/pwc-if.c --- linux-2.6.7-rc3/drivers/usb/media/pwc-if.c 2004-06-15 23:10:01.882943280 -0700 +++ linux-2.6.7/drivers/usb/media/pwc-if.c 2004-06-15 23:10:34.860331538 -0700 @@ -129,7 +129,6 @@ static int pwc_video_open(struct inode *inode, struct file *file); static int pwc_video_close(struct inode *inode, struct file *file); -static int pwc_video_release(struct video_device *); static ssize_t pwc_video_read(struct file *file, char *buf, size_t count, loff_t *ppos); static unsigned int pwc_video_poll(struct file *file, poll_table *wait); @@ -1121,12 +1120,6 @@ return 0; } -static int pwc_video_release(struct video_device *vfd) -{ - Trace(TRACE_OPEN, "pwc_video_release() called. Now what?\n"); -} - - /* * FIXME: what about two parallel reads ???? * ANSWER: Not supported. You can't open the device more than once, @@ -1855,7 +1848,7 @@ } } - pdev->vdev.release = pwc_video_release; + pdev->vdev.release = video_device_release; i = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); if (i < 0) { Err("Failed to register as video device (%d).\n", i); diff -urN linux-2.6.7-rc3/drivers/usb/serial/cyberjack.c linux-2.6.7/drivers/usb/serial/cyberjack.c --- linux-2.6.7-rc3/drivers/usb/serial/cyberjack.c 2004-06-15 23:10:01.950946143 -0700 +++ linux-2.6.7/drivers/usb/serial/cyberjack.c 2004-06-15 23:10:35.810371539 -0700 @@ -109,7 +109,7 @@ short rdtodo; /* Bytes still to read */ unsigned char wrbuf[5*64]; /* Buffer for collecting data to write */ short wrfilled; /* Overall data size we already got */ - short wrsent; /* Data akready sent */ + short wrsent; /* Data already sent */ }; /* do some startup allocations not currently performed by usb_serial_probe() */ @@ -159,8 +159,6 @@ dbg("%s - usb_clear_halt", __FUNCTION__ ); usb_clear_halt(port->serial->dev, port->write_urb->pipe); - usb_clear_halt(port->serial->dev, port->read_urb->pipe); - usb_clear_halt(port->serial->dev, port->interrupt_in_urb->pipe); /* force low_latency on so that our tty_push actually forces * the data through, otherwise it is scheduled, and with high @@ -212,7 +210,6 @@ unsigned long flags; int result; int wrexpected; - unsigned char localbuf[CYBERJACK_LOCAL_BUF_SIZE]; /* Buffer for collecting data to write */ dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - from_user %d", __FUNCTION__, from_user); @@ -229,29 +226,23 @@ spin_lock_irqsave(&priv->lock, flags); - if( (count+priv->wrfilled)>sizeof(priv->wrbuf) || - (count>sizeof(localbuf)) ) { - /* To much data for buffer. Reset buffer. */ + if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) { + /* To much data for buffer. Reset buffer. */ priv->wrfilled=0; spin_unlock_irqrestore(&priv->lock, flags); return (0); } - spin_unlock_irqrestore(&priv->lock, flags); - /* Copy data */ if (from_user) { - if (copy_from_user(localbuf, buf, count)) { + if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) { + spin_unlock_irqrestore(&priv->lock, flags); return -EFAULT; } } else { - memcpy (localbuf, buf, count); + memcpy (priv->wrbuf+priv->wrfilled, buf, count); } - spin_lock_irqsave(&priv->lock, flags); - - memcpy (priv->wrbuf+priv->wrfilled, localbuf, count); - usb_serial_debug_data (__FILE__, __FUNCTION__, count, priv->wrbuf+priv->wrfilled); priv->wrfilled += count; diff -urN linux-2.6.7-rc3/drivers/video/vga16fb.c linux-2.6.7/drivers/video/vga16fb.c --- linux-2.6.7-rc3/drivers/video/vga16fb.c 2004-06-15 23:10:02.035949720 -0700 +++ linux-2.6.7/drivers/video/vga16fb.c 2004-06-15 23:10:36.565403329 -0700 @@ -1372,8 +1372,6 @@ vga16fb.par = &vga16_par; vga16fb.flags = FBINFO_FLAG_DEFAULT; - vga16fb.fix.smem_start = VGA_MAP_MEM(vga16fb.fix.smem_start); - i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); if (ret) { diff -urN linux-2.6.7-rc3/fs/aio.c linux-2.6.7/fs/aio.c --- linux-2.6.7-rc3/fs/aio.c 2004-06-15 23:10:02.041949973 -0700 +++ linux-2.6.7/fs/aio.c 2004-06-15 23:10:36.890417014 -0700 @@ -15,7 +15,7 @@ #include #include -//#define DEBUG 1 +#define DEBUG 0 #include #include diff -urN linux-2.6.7-rc3/fs/cifs/AUTHORS linux-2.6.7/fs/cifs/AUTHORS --- linux-2.6.7-rc3/fs/cifs/AUTHORS 2004-06-15 23:10:02.057950646 -0700 +++ linux-2.6.7/fs/cifs/AUTHORS 2004-06-15 23:10:37.881458742 -0700 @@ -23,6 +23,7 @@ Shobhit Dayal Sergey Vlasov Richard Hughes +Yury Umanets Test case and Bug Report contributors ------------------------------------- @@ -30,5 +31,7 @@ and debug of problems they have found: Jochen Dolze, David Blaine, Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori, Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen, -Kieron Briggs and others. +Olaf Kirch, Kieron Briggs and others. +And thanks to the IBM LTC and Power test teams and SuSE testers for +finding multiple bugs during excellent stress test runs. diff -urN linux-2.6.7-rc3/fs/cifs/CHANGES linux-2.6.7/fs/cifs/CHANGES --- linux-2.6.7-rc3/fs/cifs/CHANGES 2004-06-15 23:10:02.057950646 -0700 +++ linux-2.6.7/fs/cifs/CHANGES 2004-06-15 23:10:37.958461984 -0700 @@ -1,3 +1,20 @@ +Version 1.18 +------------ +Do not rename hardlinked files (since that should be a noop). Flush +cached write behind data when reopening a file after session abend, +except when already in write. Grab per socket sem during reconnect +to avoid oops in sendmsg if overlapping with reconnect. + + +Version 1.17 +------------ +Update number of blocks in file so du command is happier (in Linux a fake +blocksize of 512 is required for calculating number of blocks in inode). +Fix prepare write of partial pages to read in data from server if possible. +Fix race on tcpStatus field between unmount and reconnection code, causing +cifsd process sometimes to hang around forever. Improve out of memory +checks in cifs_filldir + Version 1.16 ------------ Fix incorrect file size in file handle based setattr on big endian hardware. diff -urN linux-2.6.7-rc3/fs/cifs/README linux-2.6.7/fs/cifs/README --- linux-2.6.7-rc3/fs/cifs/README 2004-06-15 23:10:02.058950688 -0700 +++ linux-2.6.7/fs/cifs/README 2004-06-15 23:10:37.962462152 -0700 @@ -97,7 +97,9 @@ case sensitive = yes delete readonly = yes - + ea support = yes + +Note that ea support is required for supporting Linux xattrs. Some administrators also change the "map archive" and the "create mask" parameters from their default values. Creating special devices (mknod) remotely may require specifying a mkdev function to Samba. For more information on these @@ -268,11 +270,12 @@ ======================================= Informational pseudo-files: DebugData Displays information about active CIFS sessions - as well as per share statistics (if CONFIG_CIFS_STATS - is enabled in the kernel configuration). + and shares. SimultaneousOps Counter which holds maximum number of simultaneous outstanding SMB/CIFS requests. -Stats Lists summary resource usage information +Stats Lists summary resource usage information as well as per + share statistics, if CONFIG_CIFS_STATS in enabled + in the kernel configuration. Configuration pseudo-files: MultiuserMount If set to one, more than one CIFS session to diff -urN linux-2.6.7-rc3/fs/cifs/TODO linux-2.6.7/fs/cifs/TODO --- linux-2.6.7-rc3/fs/cifs/TODO 2004-06-15 23:10:02.058950688 -0700 +++ linux-2.6.7/fs/cifs/TODO 2004-06-15 23:10:37.963462195 -0700 @@ -80,27 +80,13 @@ but recognizes them 3) create of new files to FAT partitions on Windows servers can succeed but still return access denied (appears to be Windows -not client problem) and has not been reproduced recently. +server not cifs client problem) and has not been reproduced recently. NTFS partitions do not have this problem. 4) debug connectation lock test case 10 which fails against Samba (may be unmappable due to POSIX to Windows lock model differences but worth investigating). Also debug Samba to see why lock test case 7 takes longer to complete to Samba than to Windows. -5) prepare_write does not initialize pages properly when partial -page writes begin in the middle of a page (pages can get zeroed). -6) Write caching done incorrectly when files are only opened -with write permission by the application. -7) Rename of files that are hardlinked does not work correctly e.g. - ln source target - mv source target -This should be no op since files are linked but in cifs it causes -the source file to go away. This may require implementation of -the cifs POSIX extensions (Unix Extensions version 2) for -it to be done correctly since Samba is failing the rename, -(rather than ignoring it) so the client not knowing they -are linked proceeds to delete the target and then retry the -move which succeeds this time (but the source is gone). Misc testing to do ================== diff -urN linux-2.6.7-rc3/fs/cifs/cifs_debug.c linux-2.6.7/fs/cifs/cifs_debug.c --- linux-2.6.7-rc3/fs/cifs/cifs_debug.c 2004-06-15 23:10:02.059950731 -0700 +++ linux-2.6.7/fs/cifs/cifs_debug.c 2004-06-15 23:10:37.997463626 -0700 @@ -142,30 +142,10 @@ sprintf(buf, " type: %d ", tcon->fsDevInfo.DeviceType); buf += length; - if(tcon->tidStatus == CifsNeedReconnect) + if(tcon->tidStatus == CifsNeedReconnect) { buf += sprintf(buf, "\tDISCONNECTED "); -#ifdef CONFIG_CIFS_STATS - length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d", - atomic_read(&tcon->num_smbs_sent), - atomic_read(&tcon->num_oplock_brks)); - buf += length; - length = sprintf(buf,"\nReads: %d Bytes %lld", - atomic_read(&tcon->num_reads), - (long long)(tcon->bytes_read)); - buf += length; - length = sprintf(buf,"\nWrites: %d Bytes: %lld", - atomic_read(&tcon->num_writes), - (long long)(tcon->bytes_written)); - buf += length; - length = sprintf(buf, - "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d", - atomic_read(&tcon->num_opens), - atomic_read(&tcon->num_deletes), - atomic_read(&tcon->num_mkdirs), - atomic_read(&tcon->num_rmdirs)); - buf += length; -#endif - + length += 14; + } } read_unlock(&GlobalSMBSeslock); @@ -200,32 +180,80 @@ return length; } +#ifdef CONFIG_CIFS_STATS int cifs_stats_read(char *buf, char **beginBuffer, off_t offset, int length, int *eof, void *data) { - int item_length; - length = - sprintf(buf, - "Currently Allocated structures\nCIFS Sessions: %d\n",sesInfoAllocCount.counter); + int item_length,i; + struct list_head *tmp; + struct cifsTconInfo *tcon; + + length = sprintf(buf, + "Resources in use\nCIFS Session: %d\n", + sesInfoAllocCount.counter); buf += length; item_length = - sprintf(buf,"Shares (unique mount targets): %d\n",tconInfoAllocCount.counter); + sprintf(buf,"Share (unique mount targets): %d\n", + tconInfoAllocCount.counter); length += item_length; buf += item_length; item_length = - sprintf(buf,"Allocated SMB Request and Response Buffers: %d\n",bufAllocCount.counter); + sprintf(buf,"SMB Request/Response Buffer: %d\n", + bufAllocCount.counter); length += item_length; buf += item_length; item_length = - sprintf(buf,"Active Operations (MIDs in use): %d\n",midCount.counter); + sprintf(buf,"Operations (MIDs): %d\n", + midCount.counter); length += item_length; buf += item_length; - item_length = sprintf(buf,"%d sessions and %d shares reconnected after failure\n",tcpSesReconnectCount.counter,tconInfoReconnectCount.counter); + item_length = sprintf(buf, + "\n%d session %d share reconnects\n", + tcpSesReconnectCount.counter,tconInfoReconnectCount.counter); length += item_length; + buf += item_length; + + i = 0; + read_lock(&GlobalSMBSeslock); + list_for_each(tmp, &GlobalTreeConnectionList) { + i++; + tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); + item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName); + buf += item_length; + length += item_length; + if(tcon->tidStatus == CifsNeedReconnect) { + buf += sprintf(buf, "\tDISCONNECTED "); + length += 14; + } + item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d", + atomic_read(&tcon->num_smbs_sent), + atomic_read(&tcon->num_oplock_brks)); + buf += item_length; + length += item_length; + item_length = sprintf(buf,"\nReads: %d Bytes %lld", + atomic_read(&tcon->num_reads), + (long long)(tcon->bytes_read)); + buf += item_length; + item_length = sprintf(buf,"\nWrites: %d Bytes: %lld", + atomic_read(&tcon->num_writes), + (long long)(tcon->bytes_written)); + buf += item_length; + item_length = sprintf(buf, + "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d", + atomic_read(&tcon->num_opens), + atomic_read(&tcon->num_deletes), + atomic_read(&tcon->num_mkdirs), + atomic_read(&tcon->num_rmdirs)); + buf += item_length; + length += item_length; + } + read_unlock(&GlobalSMBSeslock); + return length; } +#endif struct proc_dir_entry *proc_fs_cifs; read_proc_t cifs_txanchor_read; @@ -265,10 +293,10 @@ create_proc_read_entry("SimultaneousOps", 0, proc_fs_cifs, cifs_total_xid_read, 0); - +#ifdef CONFIG_CIFS_STATS create_proc_read_entry("Stats", 0, proc_fs_cifs, cifs_stats_read, 0); - +#endif pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, cifsFYI_read, 0); if (pde) @@ -336,7 +364,9 @@ remove_proc_entry("cifsFYI", proc_fs_cifs); remove_proc_entry("traceSMB", proc_fs_cifs); remove_proc_entry("SimultaneousOps", proc_fs_cifs); +#ifdef CONFIG_CIFS_STATS remove_proc_entry("Stats", proc_fs_cifs); +#endif remove_proc_entry("MultiuserMount", proc_fs_cifs); remove_proc_entry("OplockEnabled", proc_fs_cifs); remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); @@ -370,7 +400,7 @@ return len; } static int -cifsFYI_write(struct file *file, const char *buffer, +cifsFYI_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -409,7 +439,7 @@ return len; } static int -oplockEnabled_write(struct file *file, const char *buffer, +oplockEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -449,7 +479,7 @@ return len; } static int -quotaEnabled_write(struct file *file, const char *buffer, +quotaEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -489,7 +519,7 @@ return len; } static int -linuxExtensionsEnabled_write(struct file *file, const char *buffer, +linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -529,7 +559,7 @@ return len; } static int -lookupFlag_write(struct file *file, const char *buffer, +lookupFlag_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -567,7 +597,7 @@ return len; } static int -traceSMB_write(struct file *file, const char *buffer, +traceSMB_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -606,7 +636,7 @@ return len; } static int -multiuser_mount_write(struct file *file, const char *buffer, +multiuser_mount_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -645,7 +675,7 @@ return len; } static int -extended_security_write(struct file *file, const char *buffer, +extended_security_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -684,7 +714,7 @@ return len; } static int -ntlmv2_enabled_write(struct file *file, const char *buffer, +ntlmv2_enabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -723,7 +753,7 @@ return len; } static int -packet_signing_enabled_write(struct file *file, const char *buffer, +packet_signing_enabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; diff -urN linux-2.6.7-rc3/fs/cifs/cifsfs.c linux-2.6.7/fs/cifs/cifsfs.c --- linux-2.6.7-rc3/fs/cifs/cifsfs.c 2004-06-15 23:10:02.060950773 -0700 +++ linux-2.6.7/fs/cifs/cifsfs.c 2004-06-15 23:10:38.017464468 -0700 @@ -426,7 +426,7 @@ } static ssize_t -cifs_read_wrapper(struct file * file, char *read_data, size_t read_size, +cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, loff_t * poffset) { if(file == NULL) @@ -455,7 +455,7 @@ } static ssize_t -cifs_write_wrapper(struct file * file, const char *write_data, +cifs_write_wrapper(struct file * file, const char __user *write_data, size_t write_size, loff_t * poffset) { ssize_t written; diff -urN linux-2.6.7-rc3/fs/cifs/cifsfs.h linux-2.6.7/fs/cifs/cifsfs.h --- linux-2.6.7-rc3/fs/cifs/cifsfs.h 2004-06-15 23:10:02.061950815 -0700 +++ linux-2.6.7/fs/cifs/cifsfs.h 2004-06-15 23:10:38.044465605 -0700 @@ -85,7 +85,7 @@ /* Functions related to symlinks */ extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd); -extern int cifs_readlink(struct dentry *direntry, char *buffer, int buflen); +extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen); extern int cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname); extern int cifs_removexattr(struct dentry *, const char *); @@ -93,5 +93,5 @@ size_t, int); extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); -#define CIFS_VERSION "1.16" +#define CIFS_VERSION "1.18" #endif /* _CIFSFS_H */ diff -urN linux-2.6.7-rc3/fs/cifs/cifspdu.h linux-2.6.7/fs/cifs/cifspdu.h --- linux-2.6.7-rc3/fs/cifs/cifspdu.h 2004-06-15 23:10:02.063950899 -0700 +++ linux-2.6.7/fs/cifs/cifspdu.h 2004-06-15 23:10:38.080467121 -0700 @@ -862,6 +862,10 @@ __u16 ByteCount; /* bct = 0 */ } CREATE_DIRECTORY_RSP; +/***************************************************/ +/* NT Transact structure defintions follow */ +/* Currently only ioctl and notify are implemented */ +/***************************************************/ typedef struct smb_com_transaction_ioctl_req { struct smb_hdr hdr; /* wct = 23 */ __u8 MaxSetupCount; @@ -904,29 +908,45 @@ } TRANSACT_IOCTL_RSP; typedef struct smb_com_transaction_change_notify_req { - struct smb_hdr hdr; /* wct = 23 */ - __u8 MaxSetupCount; - __u16 Reserved; - __u32 TotalParameterCount; - __u32 TotalDataCount; - __u32 MaxParameterCount; - __u32 MaxDataCount; - __u32 ParameterCount; - __u32 ParameterOffset; - __u32 DataCount; - __u32 DataOffset; - __u8 SetupCount; /* four setup words follow subcommand */ - /* SNIA spec incorrectly included spurious pad here */ - __u16 SubCommand;/* 4 = Change Notify */ + struct smb_hdr hdr; /* wct = 23 */ + __u8 MaxSetupCount; + __u16 Reserved; + __u32 TotalParameterCount; + __u32 TotalDataCount; + __u32 MaxParameterCount; + __u32 MaxDataCount; + __u32 ParameterCount; + __u32 ParameterOffset; + __u32 DataCount; + __u32 DataOffset; + __u8 SetupCount; /* four setup words follow subcommand */ + /* SNIA spec incorrectly included spurious pad here */ + __u16 SubCommand;/* 4 = Change Notify */ __u32 CompletionFilter; /* operation to monitor */ __u16 Fid; __u8 WatchTree; /* 1 = Monitor subdirectories */ + __u8 Reserved2; __u16 ByteCount; - __u8 Pad[3]; - __u8 Data[1]; +/* __u8 Pad[3];*/ +/* __u8 Data[1];*/ } TRANSACT_CHANGE_NOTIFY_REQ; -/* Completion Filter flags */ +typedef struct smb_com_transaction_change_notify_rsp { + struct smb_hdr hdr; /* wct = 18 */ + __u8 Reserved[3]; + __u32 TotalParameterCount; + __u32 TotalDataCount; + __u32 ParameterCount; + __u32 ParameterOffset; + __u32 ParameterDisplacement; + __u32 DataCount; + __u32 DataOffset; + __u32 DataDisplacement; + __u8 SetupCount; /* 0 */ + __u16 ByteCount; + /* __u8 Pad[3]; */ +} TRANSACT_CHANGE_NOTIFY_RSP; +/* Completion Filter flags for Notify */ #define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 #define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 #define FILE_NOTIFY_CHANGE_NAME 0x00000003 @@ -1026,9 +1046,12 @@ /* PathInfo/FileInfo infolevels */ #define SMB_INFO_STANDARD 1 +#define SMB_INFO_QUERY_EAS_FROM_LIST 3 +#define SMB_INFO_QUERY_ALL_EAS 4 #define SMB_INFO_IS_NAME_VALID 6 #define SMB_QUERY_FILE_BASIC_INFO 0x101 #define SMB_QUERY_FILE_STANDARD_INFO 0x102 +#define SMB_QUERY_FILE_EA_INFO 0x103 #define SMB_QUERY_FILE_NAME_INFO 0x104 #define SMB_QUERY_FILE_ALLOCATION_INFO 0x105 #define SMB_QUERY_FILE_END_OF_FILEINFO 0x106 @@ -1667,16 +1690,17 @@ }; struct fea { - unsigned char fEA; - unsigned char cbName; - unsigned short cbValue; + unsigned char EA_flags; + __u8 name_len; + __u16 value_len; char szName[1]; + /* optionally followed by value */ }; /* flags for _FEA.fEA */ #define FEA_NEEDEA 0x80 /* need EA bit */ struct fealist { - unsigned long cbList; + __u32 list_len; struct fea list[1]; }; diff -urN linux-2.6.7-rc3/fs/cifs/cifsproto.h linux-2.6.7/fs/cifs/cifsproto.h --- linux-2.6.7-rc3/fs/cifs/cifsproto.h 2004-06-15 23:10:02.063950899 -0700 +++ linux-2.6.7/fs/cifs/cifsproto.h 2004-06-15 23:10:38.085467332 -0700 @@ -244,4 +244,11 @@ const __u16 target_tid, const char *toName, const int flags, const struct nls_table *nls_codepage); +extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, + const int notify_subdirs,const __u16 netfid,__u32 filter, + const struct nls_table *nls_codepage); +extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + char * EAData, size_t size, + const struct nls_table *nls_codepage); #endif /* _CIFSPROTO_H */ diff -urN linux-2.6.7-rc3/fs/cifs/cifssmb.c linux-2.6.7/fs/cifs/cifssmb.c --- linux-2.6.7-rc3/fs/cifs/cifssmb.c 2004-06-15 23:10:02.066951025 -0700 +++ linux-2.6.7/fs/cifs/cifssmb.c 2004-06-15 23:10:38.107468258 -0700 @@ -383,8 +383,11 @@ smb_buffer_response, &length, 0); if (ses->server) { atomic_dec(&ses->server->socketUseCount); - if (atomic_read(&ses->server->socketUseCount) == 0) + if (atomic_read(&ses->server->socketUseCount) == 0) { + spin_lock(&GlobalMid_Lock); ses->server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); + } } if (pSMB) cifs_buf_release(pSMB); @@ -1464,9 +1467,9 @@ pSMB->TotalParameterCount = 0 ; pSMB->TotalDataCount = 0; - pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxParameterCount = cpu_to_le32(2); /* BB find exact data count max from sess structure BB */ - pSMB->MaxDataCount = cpu_to_le16(4000); + pSMB->MaxDataCount = cpu_to_le32(4000); pSMB->MaxSetupCount = 4; pSMB->Reserved = 0; pSMB->ParameterOffset = 0; @@ -1593,6 +1596,8 @@ } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); /* BB also check enough total bytes returned */ + /* BB we need to improve the validity checking + of these trans2 responses */ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) rc = -EIO; /* bad smb */ else if (pFindData){ @@ -2828,3 +2833,149 @@ goto setPermsRetry; return rc; } + +int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, + const int notify_subdirs, const __u16 netfid, + __u32 filter, const struct nls_table *nls_codepage) +{ + int rc = 0; + struct smb_com_transaction_change_notify_req * pSMB = NULL; + struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; + int bytes_returned; + + cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); + rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + pSMB->TotalParameterCount = 0 ; + pSMB->TotalDataCount = 0; + pSMB->MaxParameterCount = cpu_to_le32(2); + /* BB find exact data count max from sess structure BB */ + pSMB->MaxDataCount = 0; /* same in little endian or be */ + pSMB->MaxSetupCount = 4; + pSMB->Reserved = 0; + pSMB->ParameterOffset = 0; + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->SetupCount = 4; /* single byte does not need le conversion */ + pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE); + pSMB->ParameterCount = pSMB->TotalParameterCount; + if(notify_subdirs) + pSMB->WatchTree = 1; /* one byte - no le conversion needed */ + pSMB->Reserved2 = 0; + pSMB->CompletionFilter = cpu_to_le32(filter); + pSMB->Fid = netfid; /* file handle always le */ + pSMB->ByteCount = 0; + + pSMB->hdr.smb_buf_length += pSMB->ByteCount; + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Error in Notify = %d", rc)); + } + if (pSMB) + cifs_buf_release(pSMB); +/* if (rc == -EAGAIN) + goto NotifyRetry; */ + return rc; +} +#ifdef CONFIG_CIFS_XATTR +int +CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + char * EAData, size_t size, + const struct nls_table *nls_codepage) +{ + /* BB assumes one setup word */ + TRANSACTION2_QPI_REQ *pSMB = NULL; + TRANSACTION2_QPI_RSP *pSMBr = NULL; + int rc = 0; + int bytes_returned; + int name_len; + + cFYI(1, ("In Query All EAs path %s", searchName)); +QAllEAsRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { + name_len = + cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530 + /* find define for this maxpathcomponent */ + , nls_codepage); + name_len++; /* trailing null */ + name_len *= 2; + } else { /* BB improve the check for buffer overruns BB */ + name_len = strnlen(searchName, 530); + name_len++; /* trailing null */ + strncpy(pSMB->FileName, searchName, name_len); + } + + pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ + + name_len /* includes null */ ; + pSMB->TotalDataCount = 0; + pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ + pSMB->MaxSetupCount = 0; + pSMB->Reserved = 0; + pSMB->Flags = 0; + pSMB->Timeout = 0; + pSMB->Reserved2 = 0; + pSMB->ParameterOffset = cpu_to_le16(offsetof( + struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); + pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ; + pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount); + pSMB->ParameterCount = pSMB->TotalParameterCount; + pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); + pSMB->Reserved4 = 0; + pSMB->hdr.smb_buf_length += pSMB->ByteCount; + pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QueryAllEAs = %d", rc)); + } else { /* decode response */ + pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); + /* BB also check enough total bytes returned */ + /* BB we need to improve the validity checking + of these trans2 responses */ + if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512)) + rc = -EIO; /* bad smb */ + /* else if (pFindData){ + memcpy((char *) pFindData, + (char *) &pSMBr->hdr.Protocol + + pSMBr->DataOffset, kl); + }*/ else { + /* check that length of list is not more than bcc */ + /* check that each entry does not go beyond length + of list */ + /* check that each element of each entry does not + go beyond end of list */ + struct fealist * ea_response_data; + rc = 0; + /* validate_trans2_offsets() */ + /* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/ + ea_response_data = (struct fealist *) + (((char *) &pSMBr->hdr.Protocol) + + pSMBr->DataOffset); + cFYI(1,("ea length %d",ea_response_data->list_len)); + } + } + if (pSMB) + cifs_buf_release(pSMB); + if (rc == -EAGAIN) + goto QAllEAsRetry; + + return rc; +} +#endif diff -urN linux-2.6.7-rc3/fs/cifs/connect.c linux-2.6.7/fs/cifs/connect.c --- linux-2.6.7-rc3/fs/cifs/connect.c 2004-06-15 23:10:02.068951109 -0700 +++ linux-2.6.7/fs/cifs/connect.c 2004-06-15 23:10:38.129469184 -0700 @@ -95,9 +95,15 @@ struct cifsTconInfo *tcon; struct mid_q_entry * mid_entry; - if(server->tcpStatus == CifsExiting) + spin_lock(&GlobalMid_Lock); + if(server->tcpStatus == CifsExiting) { + /* the demux thread will exit normally + next time through the loop */ + spin_unlock(&GlobalMid_Lock); return rc; - server->tcpStatus = CifsNeedReconnect; + } else + server->tcpStatus = CifsNeedReconnect; + spin_unlock(&GlobalMid_Lock); server->maxBuf = 0; cFYI(1, ("Reconnecting tcp session ")); @@ -122,7 +128,8 @@ } } read_unlock(&GlobalSMBSeslock); - + /* do not want to be sending data on a socket we are freeing */ + down(&server->tcpSem); if(server->ssocket) { cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, server->ssocket->flags)); @@ -148,7 +155,7 @@ } } spin_unlock(&GlobalMid_Lock); - + up(&server->tcpSem); while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) { @@ -164,7 +171,10 @@ schedule_timeout(3 * HZ); } else { atomic_inc(&tcpSesReconnectCount); - server->tcpStatus = CifsGood; + spin_lock(&GlobalMid_Lock); + if(server->tcpStatus != CifsExiting) + server->tcpStatus = CifsGood; + spin_unlock(&GlobalMid_Lock); atomic_set(&server->inFlight,0); wake_up(&server->response_q); } @@ -243,12 +253,14 @@ /* some servers kill tcp session rather than returning smb negprot error in which case reconnecting here is not going to help - return error to mount */ + spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); wake_up(&server->response_q); break; } - cFYI(1,("Reconnecting after unexpected rcvmsg error ")); + cFYI(1,("Reconnecting after unexpected peek error %d",length)); cifs_reconnect(server); csocket = server->ssocket; wake_up(&server->response_q); @@ -268,7 +280,7 @@ length = sock_recvmsg(csocket, &smb_msg, 4, 0); cFYI(0,("Received 4 byte keep alive packet")); } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) { - iov.iov_base = smb_buffer; + iov.iov_base = smb_buffer; iov.iov_len = 4; length = sock_recvmsg(csocket, &smb_msg, 4, 0); cFYI(1,("Good RFC 1002 session rsp")); @@ -280,7 +292,9 @@ /* if nack on negprot (rather than ret of smb negprot error) reconnecting not going to help, ret error to mount */ + spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); /* wake up thread doing negprot */ wake_up(&server->response_q); break; @@ -391,7 +405,9 @@ } } } + spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); atomic_set(&server->inFlight, 0); /* Although there should not be any requests blocked on this queue it can not hurt to be paranoid and try to wake up requests @@ -595,6 +611,8 @@ } if ((temp_len = strnlen(value, 300)) < 300) { vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); + if(vol->UNC == NULL) + return 1; strcpy(vol->UNC,value); if (strncmp(vol->UNC, "//", 2) == 0) { vol->UNC[0] = '\\'; @@ -742,6 +760,8 @@ } if ((temp_len = strnlen(devname, 300)) < 300) { vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); + if(vol->UNC == NULL) + return 1; strcpy(vol->UNC,devname); if (strncmp(vol->UNC, "//", 2) == 0) { vol->UNC[0] = '\\'; @@ -1030,7 +1050,7 @@ } else { /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1,("ipv6 Socket created")); - (*csocket)->sk->sk_allocation = GFP_NOFS; + (*csocket)->sk->sk_allocation = GFP_NOFS; } } @@ -1226,6 +1246,9 @@ init_waitqueue_head(&srvTcp->response_q); init_waitqueue_head(&srvTcp->request_q); INIT_LIST_HEAD(&srvTcp->pending_mid_q); + /* at this point we are the only ones with the pointer + to the struct since the kernel thread not created yet + so no need to spinlock this init of tcpStatus */ srvTcp->tcpStatus = CifsNew; init_MUTEX(&srvTcp->tcpSem); kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, @@ -1342,9 +1365,12 @@ /* on error free sesinfo and tcon struct if needed */ if (rc) { - if(atomic_read(&srvTcp->socketUseCount) == 0) - srvTcp->tcpStatus = CifsExiting; - /* If find_unc succeeded then rc == 0 so we can not end */ + if(atomic_read(&srvTcp->socketUseCount) == 0) { + spin_lock(&GlobalMid_Lock); + srvTcp->tcpStatus = CifsExiting; + spin_unlock(&GlobalMid_Lock); + } + /* If find_unc succeeded then rc == 0 so we can not end */ if (tcon) /* up here accidently freeing someone elses tcon struct */ tconInfoFree(tcon); if (existingCifsSes == 0) { @@ -1534,7 +1560,7 @@ bcc_ptr += pSMBr->resp.SecurityBlobLength; - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -1787,7 +1813,7 @@ pSMBr->resp.SecurityBlobLength)); } - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2098,7 +2124,7 @@ ses->server->secMode |= SECMODE_SIGN_ENABLED; - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2494,7 +2520,7 @@ cFYI(1, ("NTLMSSP response to Authenticate ")); - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2693,7 +2719,7 @@ /* skip service field (NB: this field is always ASCII) */ bcc_ptr += length + 1; strncpy(tcon->treeName, tree, MAX_TREE_SIZE); - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { length = UniStrnlen((wchar_t *) bcc_ptr, 512); if (((long) bcc_ptr + (2 * length)) - (long) pByteArea(smb_buffer_response) <= @@ -2791,7 +2817,7 @@ char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; int ntlmv2_flag = FALSE; - /* what if server changes its buffer size after dropping the session? */ + /* what if server changes its buffer size after dropping the session? */ if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { rc = CIFSSMBNegotiate(xid, pSesInfo); if(rc == -EAGAIN) /* retry only once on 1st time connection */ { @@ -2799,8 +2825,15 @@ if(rc == -EAGAIN) rc = -EHOSTDOWN; } - if(rc == 0) - pSesInfo->server->tcpStatus = CifsGood; + if(rc == 0) { + spin_lock(&GlobalMid_Lock); + if(pSesInfo->server->tcpStatus != CifsExiting) + pSesInfo->server->tcpStatus = CifsGood; + else + rc = -EHOSTDOWN; + spin_unlock(&GlobalMid_Lock); + + } } if (!rc) { pSesInfo->capabilities = pSesInfo->server->capabilities; diff -urN linux-2.6.7-rc3/fs/cifs/dir.c linux-2.6.7/fs/cifs/dir.c --- linux-2.6.7-rc3/fs/cifs/dir.c 2004-06-15 23:10:02.069951151 -0700 +++ linux-2.6.7/fs/cifs/dir.c 2004-06-15 23:10:38.130469226 -0700 @@ -159,6 +159,7 @@ struct cifsFileInfo * pCifsFile = NULL; struct cifsInodeInfo * pCifsInode; int disposition = FILE_OVERWRITE_IF; + int write_only = FALSE; xid = GetXid(); @@ -176,9 +177,10 @@ if(nd) { if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY) desiredAccess = GENERIC_READ; - else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) + else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) { desiredAccess = GENERIC_WRITE; - else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) { + write_only = TRUE; + } else if ((nd->intent.open.flags & O_ACCMODE) == O_RDWR) { /* GENERIC_ALL is too much permission to request */ /* can cause unnecessary access denied on create */ /* desiredAccess = GENERIC_ALL; */ @@ -262,16 +264,25 @@ pCifsFile->invalidHandle = FALSE; pCifsFile->closePend = FALSE; init_MUTEX(&pCifsFile->fh_sem); - /* pCifsFile->pfile = file; */ /* put in at open time */ + /* put the following in at open now */ + /* pCifsFile->pfile = file; */ write_lock(&GlobalSMBSeslock); list_add(&pCifsFile->tlist,&pTcon->openFileList); pCifsInode = CIFS_I(newinode); if(pCifsInode) { - list_add(&pCifsFile->flist,&pCifsInode->openFileList); + /* if readable file instance put first in list*/ + if (write_only == TRUE) { + list_add_tail(&pCifsFile->flist, + &pCifsInode->openFileList); + } else { + list_add(&pCifsFile->flist, + &pCifsInode->openFileList); + } if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = TRUE; pCifsInode->clientCanCacheRead = TRUE; - cFYI(1,("Exclusive Oplock granted on inode %p",newinode)); + cFYI(1,("Exclusive Oplock granted on inode %p", + newinode)); } else if((oplock & 0xF) == OPLOCK_READ) pCifsInode->clientCanCacheRead = TRUE; } diff -urN linux-2.6.7-rc3/fs/cifs/fcntl.c linux-2.6.7/fs/cifs/fcntl.c --- linux-2.6.7-rc3/fs/cifs/fcntl.c 2004-06-15 23:10:02.069951151 -0700 +++ linux-2.6.7/fs/cifs/fcntl.c 2004-06-15 23:10:38.130469226 -0700 @@ -32,9 +32,12 @@ { int xid; int rc = -EINVAL; + int oplock = FALSE; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; char *full_path = NULL; + __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; + __u16 netfid; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); @@ -48,7 +51,20 @@ rc = -ENOMEM; } else { cFYI(1,("cifs dir notify on file %s",full_path)); - /* CIFSSMBNotify(xid, pTcon, full_path, cifs_sb->local_nls);*/ + rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, + GENERIC_READ | SYNCHRONIZE, 0 /* create options */, + &netfid, &oplock,NULL, cifs_sb->local_nls); + /* BB fixme - add this handle to a notify handle list */ + if(rc) { + cFYI(1,("Could not open directory for notify")); + } else { + rc = CIFSSMBNotify(xid, pTcon, 1 /* subdirs */, netfid, + filter, cifs_sb->local_nls); + /* BB add code to close file eventually (at unmount + it would close automatically but may be a way + to do it easily when inode freed or when + notify info is cleared/changed */ + } } FreeXid(xid); diff -urN linux-2.6.7-rc3/fs/cifs/file.c linux-2.6.7/fs/cifs/file.c --- linux-2.6.7-rc3/fs/cifs/file.c 2004-06-15 23:10:02.070951194 -0700 +++ linux-2.6.7/fs/cifs/file.c 2004-06-15 23:10:38.134469395 -0700 @@ -143,6 +143,10 @@ /* Also refresh inode by passing in file_info buf returned by SMBOpen and calling get_inode_info with returned buf (at least helps non-Unix server case */ + + /* BB we can not do this if this is the second open of a file + and the first handle has writebehind data, we might be + able to simply do a filemap_fdatawrite/filemap_fdatawait first */ buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); if(buf==0) { if (full_path) @@ -173,7 +177,14 @@ list_add(&pCifsFile->tlist,&pTcon->openFileList); pCifsInode = CIFS_I(file->f_dentry->d_inode); if(pCifsInode) { - list_add(&pCifsFile->flist,&pCifsInode->openFileList); + /* want handles we can use to read with first */ + /* in the list so we do not have to walk the */ + /* list to search for one in prepare_write */ + if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList); + } else { + list_add(&pCifsFile->flist,&pCifsInode->openFileList); + } write_unlock(&GlobalSMBSeslock); write_unlock(&file->f_owner.lock); if(pCifsInode->clientCanCacheRead) { @@ -256,7 +267,7 @@ return rc; } -static int cifs_reopen_file(struct inode *inode, struct file *file) +static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush) { int rc = -EACCES; int xid, oplock; @@ -268,7 +279,6 @@ int desiredAccess = 0x20197; int disposition = FILE_OPEN; __u16 netfid; - FILE_ALL_INFO * buf = NULL; if(inode == NULL) return -EBADF; @@ -321,21 +331,23 @@ else oplock = FALSE; - /* BB pass O_SYNC flag through on file attributes .. BB */ + + /* Can not refresh inode by passing in file_info buf to be returned + by SMBOpen and then calling get_inode_info with returned buf + since file might have write behind data that needs to be flushed + and server version of file size can be stale. If we + knew for sure that inode was not dirty locally we could do this */ - /* Also refresh inode by passing in file_info buf returned by SMBOpen - and calling get_inode_info with returned buf (at least - helps non-Unix server case */ - buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); +/* buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); if(buf==0) { up(&pCifsFile->fh_sem); if (full_path) kfree(full_path); FreeXid(xid); return -ENOMEM; - } + }*/ rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, - CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls); + CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls); if (rc) { up(&pCifsFile->fh_sem); cFYI(1, ("cifs_open returned 0x%x ", rc)); @@ -346,13 +358,25 @@ up(&pCifsFile->fh_sem); pCifsInode = CIFS_I(inode); if(pCifsInode) { - if (pTcon->ses->capabilities & CAP_UNIX) - rc = cifs_get_inode_info_unix(&inode, + if(can_flush) { + filemap_fdatawrite(inode->i_mapping); + filemap_fdatawait(inode->i_mapping); + /* temporarily disable caching while we + go to server to get inode info */ + pCifsInode->clientCanCacheAll = FALSE; + pCifsInode->clientCanCacheRead = FALSE; + if (pTcon->ses->capabilities & CAP_UNIX) + rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb); - else - rc = cifs_get_inode_info(&inode, - full_path, buf, inode->i_sb); - + else + rc = cifs_get_inode_info(&inode, + full_path, NULL, inode->i_sb); + } /* else we are writing out data to server already + and could deadlock if we tried to flush data, and + since we do not know if we have data that would + invalidate the current end of file on the server + we can not go to the server to get the new + inod info */ if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = TRUE; pCifsInode->clientCanCacheRead = TRUE; @@ -368,8 +392,6 @@ } } - if (buf) - kfree(buf); if (full_path) kfree(full_path); FreeXid(xid); @@ -605,7 +627,11 @@ FreeXid(xid); return total_written; } - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + /* we could deadlock if we called + filemap_fdatawait from here so tell + reopen_file not to flush data to server now */ + rc = cifs_reopen_file(file->f_dentry->d_inode, + file,FALSE); if(rc != 0) break; } @@ -701,6 +727,7 @@ cifsInode = CIFS_I(mapping->host); read_lock(&GlobalSMBSeslock); + /* BB we should start at the end */ list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { open_file = list_entry(tmp,struct cifsFileInfo, flist); if(open_file->closePend) @@ -770,6 +797,9 @@ xid = GetXid(); /* BB add check for wbc flags */ page_cache_get(page); + if (!PageUptodate(page)) { + cFYI(1,("ppw - page not up to date")); + } rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE); SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ @@ -787,8 +817,7 @@ int rc = 0; struct inode *inode = page->mapping->host; loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - /* struct cifsFileInfo *open_file; - struct cifs_sb_info *cifs_sb; */ + char * page_data; xid = GetXid(); cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to)); @@ -819,7 +848,31 @@ cFYI(1,(" SetEOF (commit write) rc = %d",rc)); }*/ } - set_page_dirty(page); + if (!PageUptodate(page)) { + position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; + /* can not rely on (or let) writepage write this data */ + if(to < offset) { + cFYI(1,("Illegal offsets, can not copy from %d to %d", + offset,to)); + FreeXid(xid); + return rc; + } + /* this is probably better than directly calling + partialpage_write since in this function + the file handle is known which we might as well + leverage */ + /* BB check if anything else missing out of ppw */ + /* such as updating last write time */ + page_data = kmap(page); + rc = cifs_write(file, page_data+offset,to-offset, + &position); + if(rc > 0) + rc = 0; + /* else if rc < 0 should we set writebehind rc? */ + kunmap(page); + } else { + set_page_dirty(page); + } FreeXid(xid); return rc; @@ -924,13 +977,18 @@ } open_file = (struct cifsFileInfo *)file->private_data; + if((file->f_flags & O_ACCMODE) == O_WRONLY) { + cFYI(1,("attempting read on write only file instance")); + } + for (total_read = 0,current_offset=read_data; read_size > total_read; total_read += bytes_read,current_offset+=bytes_read) { current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize); rc = -EAGAIN; while(rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + rc = cifs_reopen_file(file->f_dentry->d_inode, + file,TRUE); if(rc != 0) break; } @@ -1085,7 +1143,8 @@ rc = -EAGAIN; while(rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + rc = cifs_reopen_file(file->f_dentry->d_inode, + file, TRUE); if(rc != 0) break; } @@ -1169,53 +1228,105 @@ return rc; } -static int -cifs_readpage(struct file *file, struct page *page) +static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset) { - loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; char * read_data; - int rc = -EACCES; - int xid; - - xid = GetXid(); - - if (file->private_data == NULL) { - FreeXid(xid); - return -EBADF; - } - - cFYI(0,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset)); + int rc; page_cache_get(page); read_data = kmap(page); /* for reads over a certain size could initiate async read ahead */ - - rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset); - + + rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); + if (rc < 0) goto io_error; else { cFYI(1,("Bytes read %d ",rc)); } - + file->f_dentry->d_inode->i_atime = CURRENT_TIME; - + if(PAGE_CACHE_SIZE > rc) { memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc); } flush_dcache_page(page); SetPageUptodate(page); rc = 0; - + io_error: - kunmap(page); + kunmap(page); + page_cache_release(page); + return rc; +} + +static int +cifs_readpage(struct file *file, struct page *page) +{ + loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + int rc = -EACCES; + int xid; + + xid = GetXid(); + + if (file->private_data == NULL) { + FreeXid(xid); + return -EBADF; + } + + cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset)); + + rc = cifs_readpage_worker(file,page,&offset); + unlock_page(page); - page_cache_release(page); FreeXid(xid); return rc; } +/* We do not want to update the file size from server for inodes + open for write - to avoid races with writepage extending + the file - in the future we could consider allowing + refreshing the inode only on increases in the file size + but this is tricky to do without racing with writebehind + page caching in the current Linux kernel design */ + +int is_size_safe_to_change(struct cifsInodeInfo * cifsInode) +{ + struct list_head *tmp; + struct list_head *tmp1; + struct cifsFileInfo *open_file = NULL; + int rc = TRUE; + + if(cifsInode == NULL) + return rc; + + read_lock(&GlobalSMBSeslock); + list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { + open_file = list_entry(tmp,struct cifsFileInfo, flist); + if(open_file == NULL) + break; + if(open_file->closePend) + continue; + /* We check if file is open for writing, + BB we could supplement this with a check to see if file size + changes have been flushed to server - ie inode metadata dirty */ + if((open_file->pfile) && + ((open_file->pfile->f_flags & O_RDWR) || + (open_file->pfile->f_flags & O_WRONLY))) { + rc = FALSE; + break; + } + if(tmp->next == NULL) { + cFYI(1,("File instance %p removed",tmp)); + break; + } + } + read_unlock(&GlobalSMBSeslock); + return rc; +} + + void fill_in_inode(struct inode *tmp_inode, FILE_DIRECTORY_INFO * pfindData, int *pobject_type) @@ -1275,9 +1386,16 @@ atomic_set(&cifsInfo->inUse,1); } - i_size_write(tmp_inode,pfindData->EndOfFile); - tmp_inode->i_blocks = - (tmp_inode->i_blksize - 1 + pfindData->AllocationSize) >> tmp_inode->i_blkbits; + if(is_size_safe_to_change(cifsInfo)) { + /* can not safely change the file size here if the + client is writing to it due to potential races */ + i_size_write(tmp_inode,pfindData->EndOfFile); + + /* 512 bytes (2**9) is the fake blocksize that must be used */ + /* for this calculation, even though the reported blocksize is larger */ + tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9; + } + if (pfindData->AllocationSize < pfindData->EndOfFile) cFYI(1, ("Possible sparse file: allocation size less than end of file ")); cFYI(1, @@ -1348,10 +1466,17 @@ tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes); - pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile); - i_size_write(tmp_inode,pfindData->EndOfFile); - tmp_inode->i_blocks = - (tmp_inode->i_blksize - 1 + pfindData->NumOfBytes) >> tmp_inode->i_blkbits; + + if(is_size_safe_to_change(cifsInfo)) { + /* can not safely change the file size here if the + client is writing to it due to potential races */ + pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile); + i_size_write(tmp_inode,pfindData->EndOfFile); + + /* 512 bytes (2**9) is the fake blocksize that must be used */ + /* for this calculation, not the real blocksize */ + tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9; + } if (S_ISREG(tmp_inode->i_mode)) { cFYI(1, ("File inode")); @@ -1393,12 +1518,15 @@ /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */ if(*ptmp_inode == NULL) { *ptmp_inode = new_inode(file->f_dentry->d_sb); + if(*ptmp_inode == NULL) + return; d_instantiate(tmp_dentry, *ptmp_inode); } } else { tmp_dentry = d_alloc(file->f_dentry, qstring); if(tmp_dentry == NULL) { cERROR(1,("Failed allocating dentry")); + *ptmp_inode = NULL; return; } @@ -1406,6 +1534,8 @@ tmp_dentry->d_op = &cifs_dentry_ops; cFYI(0, (" instantiate dentry 0x%p with inode 0x%p ", tmp_dentry, *ptmp_inode)); + if(*ptmp_inode == NULL) + return; d_instantiate(tmp_dentry, *ptmp_inode); d_rehash(tmp_dentry); } @@ -1462,7 +1592,9 @@ pqstring->len = pfindData->FileNameLength; construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry); - + if((tmp_inode == NULL) || (tmp_dentry == NULL)) { + return -ENOMEM; + } fill_in_inode(tmp_inode, pfindData, &object_type); rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos, tmp_inode->i_ino, object_type); @@ -1488,6 +1620,9 @@ pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF); construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry); + if((tmp_inode == NULL) || (tmp_dentry == NULL)) { + return -ENOMEM; + } unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type); rc = filldir(direntry, pUnixFindData->FileName, pqstring->len, @@ -1950,17 +2085,34 @@ int cifs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { + int rc = 0; + loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; cFYI(1,("prepare write for page %p from %d to %d",page,from,to)); if (!PageUptodate(page)) { - if (to - from != PAGE_CACHE_SIZE) { + /* if (to - from != PAGE_CACHE_SIZE) { void *kaddr = kmap_atomic(page, KM_USER0); memset(kaddr, 0, from); memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); flush_dcache_page(page); kunmap_atomic(kaddr, KM_USER0); + } */ + /* If we are writing a full page it will be up to date, + no need to read from the server */ + if((to==PAGE_CACHE_SIZE) && (from == 0)) + SetPageUptodate(page); + + /* might as well read a page, it is fast enough */ + if((file->f_flags & O_ACCMODE) != O_WRONLY) { + rc = cifs_readpage_worker(file,page,&offset); + } else { + /* should we try using another + file handle if there is one - how would we lock it + to prevent close of that handle racing with this read? */ + /* In any case this will be written out by commit_write */ } - SetPageUptodate(page); } + + /* BB should we pass any errors back? e.g. if we do not have read access to the file */ return 0; } @@ -1969,8 +2121,7 @@ .readpage = cifs_readpage, .readpages = cifs_readpages, .writepage = cifs_writepage, - .prepare_write = simple_prepare_write, /* BB fixme BB */ -/* .prepare_write = cifs_prepare_write, */ /* BB removeme BB */ + .prepare_write = cifs_prepare_write, .commit_write = cifs_commit_write, /* .sync_page = cifs_sync_page, */ /*.direct_IO = */ diff -urN linux-2.6.7-rc3/fs/cifs/inode.c linux-2.6.7/fs/cifs/inode.c --- linux-2.6.7-rc3/fs/cifs/inode.c 2004-06-15 23:10:02.071951236 -0700 +++ linux-2.6.7/fs/cifs/inode.c 2004-06-15 23:10:38.135469437 -0700 @@ -30,6 +30,8 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" +extern int is_size_safe_to_change(struct cifsInodeInfo *); + int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, @@ -43,9 +45,6 @@ struct cifs_sb_info *cifs_sb = CIFS_SB(sb); char *tmp_path; -/* BB add caching check so we do not go to server to overwrite inode info to cached file - where the local file sizes are correct and the server info is stale BB */ - xid = GetXid(); pTcon = cifs_sb->tcon; @@ -125,13 +124,29 @@ inode->i_nlink = le64_to_cpu(findData.Nlinks); findData.NumOfBytes = le64_to_cpu(findData.NumOfBytes); findData.EndOfFile = le64_to_cpu(findData.EndOfFile); - i_size_write(inode,findData.EndOfFile); + + if(is_size_safe_to_change(cifsInfo)) { + /* can not safely change the file size here if the + client is writing to it due to potential races */ + + i_size_write(inode,findData.EndOfFile); /* blksize needs to be multiple of two. So safer to default to blksize and blkbits set in superblock so 2**blkbits and blksize will match */ /* inode->i_blksize = (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ - inode->i_blocks = - (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits; + + /* This seems incredibly stupid but it turns out that + i_blocks is not related to (i_size / i_blksize), instead a + size of 512 is required to be used for calculating num blocks */ + + +/* inode->i_blocks = + (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;*/ + + /* 512 bytes (2**9) is the fake blocksize that must be used */ + /* for this calculation */ + inode->i_blocks = (512 - 1 + findData.NumOfBytes) >> 9; + } if (findData.NumOfBytes < findData.EndOfFile) cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file ")); @@ -273,10 +288,18 @@ inode->i_mode &= ~(S_IWUGO); /* BB add code here - validate if device or weird share or device type? */ } - i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); + if(is_size_safe_to_change(cifsInfo)) { + /* can not safely change the file size here if the + client is writing to it due to potential races */ + + i_size_write(inode,le64_to_cpu(pfindData->EndOfFile)); + + /* 512 bytes (2**9) is the fake blocksize that must be used */ + /* for this calculation */ + inode->i_blocks = (512 - 1 + pfindData->AllocationSize) + >> 9; + } pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize); - inode->i_blocks = - (inode->i_blksize - 1 + pfindData->AllocationSize) >> inode->i_blkbits; inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); @@ -556,9 +579,38 @@ rc = CIFSSMBRename(xid, pTcon, fromName, toName, cifs_sb_source->local_nls); if(rc == -EEXIST) { - cifs_unlink(target_inode, target_direntry); - rc = CIFSSMBRename(xid, pTcon, fromName, toName, - cifs_sb_source->local_nls); + /* check if they are the same file + because rename of hardlinked files is a noop */ + FILE_UNIX_BASIC_INFO * info_buf_source; + FILE_UNIX_BASIC_INFO * info_buf_target; + + info_buf_source = + kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL); + if(info_buf_source != NULL) { + info_buf_target = info_buf_source+1; + rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, + info_buf_source, cifs_sb_source->local_nls); + if(rc == 0) { + rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName, + info_buf_target, + cifs_sb_target->local_nls); + } + if((rc == 0) && + (info_buf_source->UniqueId == + info_buf_target->UniqueId)) { + /* do not rename since the files are hardlinked + which is a noop */ + } else { + /* we either can not tell the files are hardlinked + (as with Windows servers) or files are not hardlinked + so delete the target manually before renaming to + follow POSIX rather than Windows semantics */ + cifs_unlink(target_inode, target_direntry); + rc = CIFSSMBRename(xid, pTcon, fromName, toName, + cifs_sb_source->local_nls); + } + kfree(info_buf_source); + } /* if we can not get memory just leave rc as EEXIST */ } if((rc == -EIO)||(rc == -EEXIST)) { diff -urN linux-2.6.7-rc3/fs/cifs/link.c linux-2.6.7/fs/cifs/link.c --- linux-2.6.7-rc3/fs/cifs/link.c 2004-06-15 23:10:02.072951278 -0700 +++ linux-2.6.7/fs/cifs/link.c 2004-06-15 23:10:38.136469479 -0700 @@ -210,7 +210,7 @@ } int -cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) +cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) { struct inode *inode = direntry->d_inode; int rc = -EACCES; diff -urN linux-2.6.7-rc3/fs/cifs/transport.c linux-2.6.7/fs/cifs/transport.c --- linux-2.6.7-rc3/fs/cifs/transport.c 2004-06-15 23:10:02.073951320 -0700 +++ linux-2.6.7/fs/cifs/transport.c 2004-06-15 23:10:38.137469521 -0700 @@ -120,13 +120,13 @@ unsigned int smb_buf_length, struct sockaddr *sin) { int rc = 0; + int i = 0; struct msghdr smb_msg; struct iovec iov; mm_segment_t temp_fs; if(ssocket == NULL) return -ENOTSOCK; /* BB eventually add reconnect code here */ -/* ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */ iov.iov_base = smb_buffer; iov.iov_len = smb_buf_length + 4; @@ -152,6 +152,14 @@ while(iov.iov_len > 0) { rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { + i++; + if(i > 60) { + cERROR(1, + ("sends on sock %p stuck for 30 seconds", + ssocket)); + rc = -EAGAIN; + break; + } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/2); continue; @@ -260,7 +268,17 @@ midQ->midState = MID_REQUEST_SUBMITTED; rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, (struct sockaddr *) &(ses->server->addr.sockAddr)); - up(&ses->server->tcpSem); + if(rc < 0) { + DeleteMidQEntry(midQ); + up(&ses->server->tcpSem); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return rc; + } else + up(&ses->server->tcpSem); if (long_op == -1) goto cifs_no_response_exit; else if (long_op == 2) /* writes past end of file can take looooong time */ diff -urN linux-2.6.7-rc3/fs/cifs/xattr.c linux-2.6.7/fs/cifs/xattr.c --- linux-2.6.7-rc3/fs/cifs/xattr.c 2004-05-09 19:32:29.000000000 -0700 +++ linux-2.6.7/fs/cifs/xattr.c 2004-06-15 23:10:38.137469521 -0700 @@ -20,37 +20,68 @@ */ #include +#include "cifsfs.h" +#include "cifspdu.h" +#include "cifsglob.h" +#include "cifsproto.h" +#include "cifs_debug.h" int cifs_removexattr(struct dentry * direntry, const char * name) { - int rc = -EOPNOTSUPP; - return rc; + int rc = -EOPNOTSUPP; + return rc; } int cifs_setxattr(struct dentry * direntry, const char * name, const void * value, size_t size, int flags) { - int rc = -EOPNOTSUPP; - return rc; + int rc = -EOPNOTSUPP; + return rc; } ssize_t cifs_getxattr(struct dentry * direntry, const char * name, void * value, size_t size) { - ssize_t rc = -EOPNOTSUPP; - return rc; + ssize_t rc = -EOPNOTSUPP; + return rc; } ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size) { - ssize_t rc = -EOPNOTSUPP; - + ssize_t rc = -EOPNOTSUPP; +#ifdef CONFIG_CIFS_XATTR + int xid; + struct cifs_sb_info *cifs_sb; + struct cifsTconInfo *pTcon; + struct super_block * sb; + char * full_path; + if(direntry == NULL) + return -EIO; + if(direntry->d_inode == NULL) + return -EIO; + sb = direntry->d_inode->i_sb; + if(sb == NULL) + return -EIO; + xid = GetXid(); + + cifs_sb = CIFS_SB(sb); + pTcon = cifs_sb->tcon; + + down(&sb->s_vfs_rename_sem); + full_path = build_path_from_dentry(direntry); + up(&sb->s_vfs_rename_sem); + if(full_path == NULL) { + FreeXid(xid); + return -ENOMEM; + } /* return dosattributes as pseudo xattr */ /* return alt name if available as pseudo attr */ /* if proc/fs/cifs/streamstoxattr is set then search server for EAs or streams to returns as xattrs */ - - return rc; + rc = CIFSSMBQAllEAs(xid,pTcon,full_path,ea_data,ea_size,cifs_sb->local_nls); + FreeXid(xid); +#endif + return rc; } diff -urN linux-2.6.7-rc3/fs/eventpoll.c linux-2.6.7/fs/eventpoll.c --- linux-2.6.7-rc3/fs/eventpoll.c 2004-06-15 23:10:02.091952078 -0700 +++ linux-2.6.7/fs/eventpoll.c 2004-06-15 23:10:38.396480427 -0700 @@ -499,6 +499,11 @@ DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n", current, size)); + /* Sanity check on the size parameter */ + error = -EINVAL; + if (size <= 0) + goto eexit_1; + /* Correctly size the hash */ hashbits = ep_get_hash_bits((unsigned int) size); diff -urN linux-2.6.7-rc3/fs/ext3/super.c linux-2.6.7/fs/ext3/super.c --- linux-2.6.7-rc3/fs/ext3/super.c 2004-06-15 23:10:02.100952456 -0700 +++ linux-2.6.7/fs/ext3/super.c 2004-06-15 23:10:38.852499628 -0700 @@ -1875,13 +1875,17 @@ static void ext3_mark_recovery_complete(struct super_block * sb, struct ext3_super_block * es) { - journal_flush(EXT3_SB(sb)->s_journal); + journal_t *journal = EXT3_SB(sb)->s_journal; + + journal_lock_updates(journal); + journal_flush(journal); if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && sb->s_flags & MS_RDONLY) { EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); sb->s_dirt = 0; ext3_commit_super(sb, es, 1); } + journal_unlock_updates(journal); } /* diff -urN linux-2.6.7-rc3/fs/fs-writeback.c linux-2.6.7/fs/fs-writeback.c --- linux-2.6.7-rc3/fs/fs-writeback.c 2004-06-15 23:10:02.103952583 -0700 +++ linux-2.6.7/fs/fs-writeback.c 2004-06-15 23:10:38.946503586 -0700 @@ -396,9 +396,19 @@ sb = sb_entry(super_blocks.prev); for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) { if (!list_empty(&sb->s_dirty) || !list_empty(&sb->s_io)) { + /* we're making our own get_super here */ sb->s_count++; spin_unlock(&sb_lock); - sync_sb_inodes(sb, wbc); + /* + * If we can't get the readlock, there's no sense in + * waiting around, most of the time the FS is going to + * be unmounted by the time it is released. + */ + if (down_read_trylock(&sb->s_umount)) { + if (sb->s_root) + sync_sb_inodes(sb, wbc); + up_read(&sb->s_umount); + } spin_lock(&sb_lock); if (__put_super(sb)) goto restart; @@ -423,18 +433,15 @@ */ void sync_inodes_sb(struct super_block *sb, int wait) { - struct page_state ps; struct writeback_control wbc = { - .bdi = NULL, .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, - .older_than_this = NULL, - .nr_to_write = 0, }; + unsigned long nr_dirty = read_page_state(nr_dirty); + unsigned long nr_unstable = read_page_state(nr_unstable); - get_page_state(&ps); - wbc.nr_to_write = ps.nr_dirty + ps.nr_unstable + + wbc.nr_to_write = nr_dirty + nr_unstable + (inodes_stat.nr_inodes - inodes_stat.nr_unused) + - ps.nr_dirty + ps.nr_unstable; + nr_dirty + nr_unstable; wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */ spin_lock(&inode_lock); sync_sb_inodes(sb, &wbc); diff -urN linux-2.6.7-rc3/fs/jbd/commit.c linux-2.6.7/fs/jbd/commit.c --- linux-2.6.7-rc3/fs/jbd/commit.c 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/fs/jbd/commit.c 2004-06-15 23:10:39.650533230 -0700 @@ -412,7 +412,8 @@ tagp = &bh->b_data[sizeof(journal_header_t)]; space_left = bh->b_size - sizeof(journal_header_t); first_tag = 1; - set_bit(BH_JWrite, &bh->b_state); + set_buffer_jwrite(bh); + set_buffer_dirty(bh); wbuf[bufs++] = bh; /* Record it so that we can wait for IO @@ -638,7 +639,8 @@ JBUFFER_TRACE(descriptor, "write commit block"); { struct buffer_head *bh = jh2bh(descriptor); - set_buffer_uptodate(bh); + + set_buffer_dirty(bh); sync_dirty_buffer(bh); if (unlikely(!buffer_uptodate(bh))) err = -EIO; diff -urN linux-2.6.7-rc3/fs/jbd/journal.c linux-2.6.7/fs/jbd/journal.c --- linux-2.6.7-rc3/fs/jbd/journal.c 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/fs/jbd/journal.c 2004-06-15 23:10:39.742537104 -0700 @@ -585,9 +585,13 @@ * We play buffer_head aliasing tricks to write data/metadata blocks to * the journal without copying their contents, but for journal * descriptor blocks we do need to generate bona fide buffers. + * + * After the caller of journal_get_descriptor_buffer() has finished modifying + * the buffer's contents they really should run flush_dcache_page(bh->b_page). + * But we don't bother doing that, so there will be coherency problems with + * mmaps of blockdevs which hold live JBD-controlled filesystems. */ - -struct journal_head * journal_get_descriptor_buffer(journal_t *journal) +struct journal_head *journal_get_descriptor_buffer(journal_t *journal) { struct buffer_head *bh; unsigned long blocknr; @@ -599,8 +603,10 @@ return NULL; bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); + lock_buffer(bh); memset(bh->b_data, 0, journal->j_blocksize); - bh->b_state |= (1 << BH_Dirty); + set_buffer_uptodate(bh); + unlock_buffer(bh); BUFFER_TRACE(bh, "return this buffer"); return journal_add_journal_head(bh); } diff -urN linux-2.6.7-rc3/fs/jbd/revoke.c linux-2.6.7/fs/jbd/revoke.c --- linux-2.6.7-rc3/fs/jbd/revoke.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/fs/jbd/revoke.c 2004-06-15 23:10:39.779538662 -0700 @@ -522,7 +522,7 @@ kmem_cache_free(revoke_record_cache, record); } } - if (descriptor) + if (descriptor) flush_descriptor(journal, descriptor, offset); jbd_debug(1, "Wrote %d revoke records\n", count); } @@ -606,7 +606,7 @@ header->r_count = htonl(offset); set_buffer_jwrite(bh); BUFFER_TRACE(bh, "write"); - set_buffer_uptodate(bh); + set_buffer_dirty(bh); ll_rw_block(WRITE, 1, &bh); } #endif diff -urN linux-2.6.7-rc3/fs/jfs/jfs_btree.h linux-2.6.7/fs/jfs/jfs_btree.h --- linux-2.6.7-rc3/fs/jfs/jfs_btree.h 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/fs/jfs/jfs_btree.h 2004-06-15 23:10:39.913544304 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) International Business Machines Corp., 2000-2001 + * Copyright (C) International Business Machines Corp., 2000-2004 * * 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 @@ -108,13 +108,12 @@ * record the path traversed during the search; * top frame record the leaf page/entry selected. */ -#define MAXTREEHEIGHT 8 struct btframe { /* stack frame */ s64 bn; /* 8: */ s16 index; /* 2: */ - s16 lastindex; /* 2: */ - struct metapage *mp; /* 4: */ -}; /* (16) */ + s16 lastindex; /* 2: unused */ + struct metapage *mp; /* 4/8: */ +}; /* (16/24) */ struct btstack { struct btframe *top; @@ -125,12 +124,15 @@ #define BT_CLR(btstack)\ (btstack)->top = (btstack)->stack +#define BT_STACK_FULL(btstack)\ + ( (btstack)->top == &((btstack)->stack[MAXTREEHEIGHT-1])) + #define BT_PUSH(BTSTACK, BN, INDEX)\ {\ + assert(!BT_STACK_FULL(BTSTACK));\ (BTSTACK)->top->bn = BN;\ (BTSTACK)->top->index = INDEX;\ ++(BTSTACK)->top;\ - assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\ } #define BT_POP(btstack)\ @@ -139,6 +141,16 @@ #define BT_STACK(btstack)\ ( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top ) +static inline void BT_STACK_DUMP(struct btstack *btstack) +{ + int i; + printk("btstack dump:\n"); + for (i = 0; i < MAXTREEHEIGHT; i++) + printk(KERN_ERR "bn = %Lx, index = %d\n", + btstack->stack[i].bn, + btstack->stack[i].index); +} + /* retrieve search results */ #define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\ {\ diff -urN linux-2.6.7-rc3/fs/jfs/jfs_dmap.c linux-2.6.7/fs/jfs/jfs_dmap.c --- linux-2.6.7-rc3/fs/jfs/jfs_dmap.c 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/fs/jfs/jfs_dmap.c 2004-06-15 23:10:39.966546536 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) International Business Machines Corp., 2000-2003 + * Copyright (C) International Business Machines Corp., 2000-2004 * * 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 @@ -382,7 +382,7 @@ IREAD_LOCK(ipbmap); /* block to be freed better be within the mapsize. */ - if (blkno + nblocks > bmp->db_mapsize) { + if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) { IREAD_UNLOCK(ipbmap); printk(KERN_ERR "blkno = %Lx, nblocks = %Lx\n", (unsigned long long) blkno, diff -urN linux-2.6.7-rc3/fs/jfs/jfs_dtree.c linux-2.6.7/fs/jfs/jfs_dtree.c --- linux-2.6.7-rc3/fs/jfs/jfs_dtree.c 2004-06-15 23:10:02.162955066 -0700 +++ linux-2.6.7/fs/jfs/jfs_dtree.c 2004-06-15 23:10:40.010548389 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (C) International Business Machines Corp., 2000-2003 + * Copyright (C) International Business Machines Corp., 2000-2004 * * 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 @@ -378,6 +378,8 @@ * It's time to move the inline table to an external * page and begin to build the xtree */ + if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) + goto clean_up; /* No space */ /* * Save the table, we're going to overwrite it with the @@ -394,8 +396,8 @@ /* * Allocate the first block & add it to the xtree */ - xaddr = 0; if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { + /* This really shouldn't fail */ jfs_warn("add_index: xtInsert failed!"); memcpy(&jfs_ip->i_dirtable, temp_table, sizeof (temp_table)); @@ -764,11 +766,12 @@ */ getChild: /* update max. number of pages to split */ - if (btstack->nsplit >= 8) { + if (BT_STACK_FULL(btstack)) { /* Something's corrupted, mark filesytem dirty so * chkdsk will fix it. */ jfs_error(sb, "stack overrun in dtSearch!"); + BT_STACK_DUMP(btstack); rc = -EIO; goto out; } @@ -975,8 +978,10 @@ n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */ if (n <= split->nslot) xlen++; - if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) + if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr))) { + DT_PUTPAGE(smp); goto freeKeyName; + } pxdlist.maxnpxd = 1; pxdlist.npxd = 0; @@ -3342,6 +3347,12 @@ /* * descend down to leftmost child page */ + if (BT_STACK_FULL(btstack)) { + DT_PUTPAGE(mp); + jfs_error(ip->i_sb, "dtReadFirst: btstack overrun"); + BT_STACK_DUMP(btstack); + return -EIO; + } /* push (bn, index) of the parent page/entry */ BT_PUSH(btstack, bn, 0); diff -urN linux-2.6.7-rc3/fs/jfs/jfs_metapage.c linux-2.6.7/fs/jfs/jfs_metapage.c --- linux-2.6.7-rc3/fs/jfs/jfs_metapage.c 2004-06-15 23:10:02.165955192 -0700 +++ linux-2.6.7/fs/jfs/jfs_metapage.c 2004-06-15 23:10:40.159554663 -0700 @@ -239,6 +239,7 @@ spin_unlock(&meta_lock); if (test_bit(META_stale, &mp->flag)) { release_metapage(mp); + yield(); /* Let other waiters release it, too */ goto again; } if (test_bit(META_discard, &mp->flag)) { diff -urN linux-2.6.7-rc3/fs/jfs/jfs_txnmgr.c linux-2.6.7/fs/jfs/jfs_txnmgr.c --- linux-2.6.7-rc3/fs/jfs/jfs_txnmgr.c 2004-06-15 23:10:02.169955361 -0700 +++ linux-2.6.7/fs/jfs/jfs_txnmgr.c 2004-06-15 23:10:40.205556600 -0700 @@ -1747,7 +1747,10 @@ if (lwm == next) goto out; - assert(lwm < next); + if (lwm > next) { + jfs_err("xtLog: lwm > next\n"); + goto out; + } tlck->flag |= tlckUPDATEMAP; xadlock->flag = mlckALLOCXADLIST; xadlock->count = next - lwm; @@ -1913,25 +1916,18 @@ /* * write log records */ - /* - * allocate entries XAD[lwm:next]: - */ - if (lwm < next) { - /* log after-image for logredo(): - * logredo() will update bmap for alloc of new/extended - * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from - * after-image of XADlist; - * logredo() resets (XAD_NEW|XAD_EXTEND) flag when - * applying the after-image to the meta-data page. - */ - lrd->type = cpu_to_le16(LOG_REDOPAGE); - PXDaddress(pxd, mp->index); - PXDlength(pxd, - mp->logical_size >> tblk->sb-> - s_blocksize_bits); - lrd->backchain = - cpu_to_le32(lmLog(log, tblk, lrd, tlck)); - } + /* log after-image for logredo(): + * + * logredo() will update bmap for alloc of new/extended + * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from + * after-image of XADlist; + * logredo() resets (XAD_NEW|XAD_EXTEND) flag when + * applying the after-image to the meta-data page. + */ + lrd->type = cpu_to_le16(LOG_REDOPAGE); + PXDaddress(pxd, mp->index); + PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); + lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); /* * truncate entry XAD[twm == next - 1]: @@ -2624,6 +2620,7 @@ lid_t lid, next; struct metapage *mp; struct tblock *tblk = tid_to_tblock(tid); + struct tlock *tlck; jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty); @@ -2631,9 +2628,10 @@ * free tlocks of the transaction */ for (lid = tblk->next; lid; lid = next) { - next = lid_to_tlock(lid)->next; - - mp = lid_to_tlock(lid)->mp; + tlck = lid_to_tlock(lid); + next = tlck->next; + mp = tlck->mp; + JFS_IP(tlck->ip)->xtlid = 0; if (mp) { mp->lid = 0; diff -urN linux-2.6.7-rc3/fs/jfs/jfs_types.h linux-2.6.7/fs/jfs/jfs_types.h --- linux-2.6.7-rc3/fs/jfs/jfs_types.h 2004-06-15 23:10:02.171955445 -0700 +++ linux-2.6.7/fs/jfs/jfs_types.h 2004-06-15 23:10:40.226557484 -0700 @@ -113,11 +113,12 @@ #define addressPXD(pxd)\ ( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2)) +#define MAXTREEHEIGHT 8 /* pxd list */ struct pxdlist { s16 maxnpxd; s16 npxd; - pxd_t pxd[8]; + pxd_t pxd[MAXTREEHEIGHT]; }; diff -urN linux-2.6.7-rc3/fs/jfs/namei.c linux-2.6.7/fs/jfs/namei.c --- linux-2.6.7-rc3/fs/jfs/namei.c 2004-06-15 23:10:02.172955487 -0700 +++ linux-2.6.7/fs/jfs/namei.c 2004-06-15 23:10:40.228557568 -0700 @@ -858,7 +858,7 @@ unchar *i_fastsymlink; s64 xlen = 0; int bmask = 0, xsize; - s64 xaddr; + s64 extent = 0, xaddr; struct metapage *mp; struct super_block *sb; struct tblock *tblk; @@ -892,29 +892,11 @@ down(&JFS_IP(dip)->commit_sem); down(&JFS_IP(ip)->commit_sem); - if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) - goto out3; - tblk = tid_to_tblock(tid); tblk->xflag |= COMMIT_CREATE; tblk->ino = ip->i_ino; tblk->u.ixpxd = JFS_IP(ip)->ixpxd; - /* - * create entry for symbolic link in parent directory - */ - - ino = ip->i_ino; - - - - if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { - jfs_err("jfs_symlink: dtInsert returned %d", rc); - /* discard ne inode */ - goto out3; - - } - /* fix symlink access permission * (dir_create() ANDs in the u.u_cmask, * but symlinks really need to be 777 access) @@ -922,7 +904,7 @@ ip->i_mode |= 0777; /* - * write symbolic link target path name + * write symbolic link target path name */ xtInitRoot(tid, ip); @@ -966,37 +948,48 @@ xsize = (ssize + bmask) & ~bmask; xaddr = 0; xlen = xsize >> JFS_SBI(sb)->l2bsize; - if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) { - ip->i_size = ssize - 1; - while (ssize) { - int copy_size = min(ssize, PSIZE); - - mp = get_metapage(ip, xaddr, PSIZE, 1); - - if (mp == NULL) { - dtDelete(tid, dip, &dname, &ino, - JFS_REMOVE); - rc = -EIO; - goto out3; - } - memcpy(mp->data, name, copy_size); - flush_metapage(mp); -#if 0 - set_buffer_uptodate(bp); - mark_buffer_dirty(bp, 1); - if (IS_SYNC(dip)) - sync_dirty_buffer(bp); - brelse(bp); -#endif /* 0 */ - ssize -= copy_size; - xaddr += JFS_SBI(sb)->nbperpage; - } - ip->i_blocks = LBLK2PBLK(sb, xlen); - } else { - dtDelete(tid, dip, &dname, &ino, JFS_REMOVE); + if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0))) { + txAbort(tid, 0); rc = -ENOSPC; goto out3; } + extent = xaddr; + ip->i_size = ssize - 1; + while (ssize) { + /* This is kind of silly since PATH_MAX == 4K */ + int copy_size = min(ssize, PSIZE); + + mp = get_metapage(ip, xaddr, PSIZE, 1); + + if (mp == NULL) { + dbFree(ip, extent, xlen); + rc = -EIO; + txAbort(tid, 0); + goto out3; + } + memcpy(mp->data, name, copy_size); + flush_metapage(mp); + ssize -= copy_size; + name += copy_size; + xaddr += JFS_SBI(sb)->nbperpage; + } + ip->i_blocks = LBLK2PBLK(sb, xlen); + } + + /* + * create entry for symbolic link in parent directory + */ + rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE); + if (rc == 0) { + ino = ip->i_ino; + rc = dtInsert(tid, dip, &dname, &ino, &btstack); + } + if (rc) { + if (xlen) + dbFree(ip, extent, xlen); + txAbort(tid, 0); + /* discard new inode */ + goto out3; } insert_inode_hash(ip); @@ -1004,23 +997,11 @@ /* * commit update of parent directory and link object - * - * if extent allocation failed (ENOSPC), - * the parent inode is committed regardless to avoid - * backing out parent directory update (by dtInsert()) - * and subsequent dtDelete() which is harmless wrt - * integrity concern. - * the symlink inode will be freed by iput() at exit - * as it has a zero link count (by dtDelete()) and - * no permanant resources. */ iplist[0] = dip; - if (rc == 0) { - iplist[1] = ip; - rc = txCommit(tid, 2, &iplist[0], 0); - } else - rc = txCommit(tid, 1, &iplist[0], 0); + iplist[1] = ip; + rc = txCommit(tid, 2, &iplist[0], 0); out3: txEnd(tid); @@ -1223,7 +1204,7 @@ /* Linelock header of dtree */ tlck = txLock(tid, old_ip, (struct metapage *) &JFS_IP(old_ip)->bxflag, - tlckDTREE | tlckBTROOT); + tlckDTREE | tlckBTROOT | tlckRELINK); dtlck = (struct dt_lock *) & tlck->lock; ASSERT(dtlck->index == 0); lv = & dtlck->lv[0]; diff -urN linux-2.6.7-rc3/fs/jfs/xattr.c linux-2.6.7/fs/jfs/xattr.c --- linux-2.6.7-rc3/fs/jfs/xattr.c 2004-06-15 23:10:02.174955571 -0700 +++ linux-2.6.7/fs/jfs/xattr.c 2004-06-15 23:10:40.233557779 -0700 @@ -688,17 +688,26 @@ } inode->i_mode = mode; mark_inode_dirty(inode); - if (rc == 0) - value = NULL; } /* * We're changing the ACL. Get rid of the cached one */ acl =JFS_IP(inode)->i_acl; - if (acl && (acl != JFS_ACL_NOT_CACHED)) + if (acl != JFS_ACL_NOT_CACHED) posix_acl_release(acl); JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED; + + return 0; } else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) { + acl = posix_acl_from_xattr(value, value_len); + if (IS_ERR(acl)) { + rc = PTR_ERR(acl); + printk(KERN_ERR "posix_acl_from_xattr returned %d\n", + rc); + return rc; + } + posix_acl_release(acl); + /* * We're changing the default ACL. Get rid of the cached one */ @@ -706,13 +715,11 @@ if (acl && (acl != JFS_ACL_NOT_CACHED)) posix_acl_release(acl); JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED; - } else - /* Invalid xattr name */ - return -EINVAL; - return 0; -#else /* CONFIG_JFS_POSIX_ACL */ - return -EOPNOTSUPP; + + return 0; + } #endif /* CONFIG_JFS_POSIX_ACL */ + return -EOPNOTSUPP; } static int can_set_xattr(struct inode *inode, const char *name, diff -urN linux-2.6.7-rc3/fs/nfs/write.c linux-2.6.7/fs/nfs/write.c --- linux-2.6.7-rc3/fs/nfs/write.c 2004-06-15 23:10:02.188956160 -0700 +++ linux-2.6.7/fs/nfs/write.c 2004-06-15 23:10:40.654575506 -0700 @@ -314,7 +314,7 @@ if (err >= 0) { err = 0; if (wbc->for_reclaim) - err = WRITEPAGE_ACTIVATE; + nfs_flush_inode(inode, 0, 0, FLUSH_STABLE); } } else { err = nfs_writepage_sync(NULL, inode, page, 0, @@ -327,8 +327,7 @@ } unlock_kernel(); out: - if (err != WRITEPAGE_ACTIVATE) - unlock_page(page); + unlock_page(page); if (inode_referenced) iput(inode); return err; diff -urN linux-2.6.7-rc3/fs/ntfs/ChangeLog linux-2.6.7/fs/ntfs/ChangeLog --- linux-2.6.7-rc3/fs/ntfs/ChangeLog 2004-06-15 23:10:02.198956581 -0700 +++ linux-2.6.7/fs/ntfs/ChangeLog 2004-06-15 23:10:40.724578454 -0700 @@ -1,4 +1,4 @@ -ToDo: +ToDo/Notes: - Find and fix bugs. - Either invalidate quotas or update the quota charges on NTFS 3.x volumes with quota tracking enabled ($Quota). @@ -11,8 +11,10 @@ pages as nothing can dirty a page other than ourselves. Should this change, we will really need to roll our own ->set_page_dirty(). - Implement sops->dirty_inode() to implement {a,m,c}time updates and - such things. - - Implement sops->write_inode(). + such things. This should probably just flag the ntfs inode such that + sops->write_inode(), i.e. ntfs_write_inode(), will copy the times + when it is invoked rather than having to update the mft record + every time. - In between ntfs_prepare/commit_write, need exclusion between simultaneous file extensions. Need perhaps an NInoResizeUnderway() flag which we can set in ntfs_prepare_write() and clear again in @@ -24,6 +26,71 @@ OTOH, perhaps i_sem, which is held accross generic_file_write is sufficient for synchronisation here. We then just need to make sure ntfs_readpage/writepage/truncate interoperate properly with us. + - Implement mft.c::sync_mft_mirror_umount(). We currently will just + leave the volume dirty on umount if the final iput(vol->mft_ino) + causes a write of any mirrored mft records due to the mft mirror + inode having been discarded already. Whether this can actually ever + happen is unclear however so it is worth waiting until someone hits + the problem. + - Enable the code for setting the NT4 compatibility flag when we start + making NTFS 1.2 specific modifications. + +2.1.14 - Fix an NFSd caused deadlock reported by several users. + + - Modify fs/ntfs/ntfs_readdir() to copy the index root attribute value + to a buffer so that we can put the search context and unmap the mft + record before calling the filldir() callback. We need to do this + because of NFSd which calls ->lookup() from its filldir callback() + and this causes NTFS to deadlock as ntfs_lookup() maps the mft record + of the directory and since ntfs_readdir() has got it mapped already + ntfs_lookup() deadlocks. + +2.1.13 - Enable overwriting of resident files and housekeeping of system files. + + - Implement writing of mft records (fs/ntfs/mft.[hc]), which includes + keeping the mft mirror in sync with the mft when mirrored mft records + are written. The functions are write_mft_record{,_nolock}(). The + implementation is quite rudimentary for now with lots of things not + implemented yet but I am not sure any of them can actually occur so + I will wait for people to hit each one and only then implement it. + - Commit open system inodes at umount time. This should make it + virtually impossible for sync_mft_mirror_umount() to ever be needed. + - Implement ->write_inode (fs/ntfs/inode.c::ntfs_write_inode()) for the + ntfs super operations. This gives us inode writing via the VFS inode + dirty code paths. Note: Access time updates are not implemented yet. + - Implement fs/ntfs/mft.[hc]::{,__}mark_mft_record_dirty() and make + fs/ntfs/aops.c::ntfs_writepage() and ntfs_commit_write() use it, thus + finally enabling resident file overwrite! (-8 This also includes a + placeholder for ->writepage (ntfs_mft_writepage()), which for now + just redirties the page and returns. Also, at umount time, we for + now throw away all mft data page cache pages after the last call to + ntfs_commit_inode() in the hope that all inodes will have been + written out by then and hence no dirty (meta)data will be lost. We + also check for this case and emit an error message telling the user + to run chkdsk. + - Use set_page_writeback() and end_page_writeback() in the resident + attribute code path of fs/ntfs/aops.c::ntfs_writepage() otherwise + the radix-tree tag PAGECACHE_TAG_DIRTY remains set even though the + page is clean. + - Implement ntfs_mft_writepage() so it now checks if any of the mft + records in the page are dirty and if so redirties the page and + returns. Otherwise it just returns (after doing set_page_writeback(), + unlock_page(), end_page_writeback() or the radix-tree tag + PAGECACHE_TAG_DIRTY remains set even though the page is clean), thus + alowing the VM to do with the page as it pleases. Also, at umount + time, now only throw away dirty mft (meta)data pages if dirty inodes + are present and ask the user to email us if they see this happening. + - Add functions ntfs_{clear,set}_volume_flags(), to modify the volume + information flags (fs/ntfs/super.c). + - Mark the volume dirty when (re)mounting read-write and mark it clean + when unmounting or remounting read-only. If any volume errors are + found, the volume is left marked dirty to force chkdsk to run. + - Add code to set the NT4 compatibility flag when (re)mounting + read-write for newer NTFS versions but leave it commented out for now + since we do not make any modifications that are NTFS 1.2 specific yet + and since setting this flag breaks Captive-NTFS which is not nice. + This code must be enabled once we start writing NTFS 1.2 specific + changes otherwise Windows NTFS driver might crash / cause corruption. 2.1.12 - Fix the second fix to the decompression engine and some cleanups. diff -urN linux-2.6.7-rc3/fs/ntfs/Makefile linux-2.6.7/fs/ntfs/Makefile --- linux-2.6.7-rc3/fs/ntfs/Makefile 2004-06-15 23:10:02.199956624 -0700 +++ linux-2.6.7/fs/ntfs/Makefile 2004-06-15 23:10:40.767580265 -0700 @@ -5,7 +5,7 @@ ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \ mst.o namei.o super.o sysctl.o unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.12\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.14\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff -urN linux-2.6.7-rc3/fs/ntfs/aops.c linux-2.6.7/fs/ntfs/aops.c --- linux-2.6.7-rc3/fs/ntfs/aops.c 2004-06-15 23:10:02.200956666 -0700 +++ linux-2.6.7/fs/ntfs/aops.c 2004-06-15 23:10:40.807581949 -0700 @@ -478,8 +478,8 @@ ni = NTFS_I(vi); vol = ni->vol; - ntfs_debug("Entering for inode %li, attribute type 0x%x, page index " - "0x%lx.\n", vi->i_ino, ni->type, page->index); + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " + "0x%lx.", vi->i_ino, ni->type, page->index); BUG_ON(!NInoNonResident(ni)); BUG_ON(NInoMstProtected(ni)); @@ -778,9 +778,8 @@ * * For resident attributes, OTOH, ntfs_writepage() writes the @page by copying * the data to the mft record (which at this stage is most likely in memory). - * Thus, in this case, I/O is synchronous, as even if the mft record is not - * cached at this point in time, we need to wait for it to be read in before we - * can do the copy. + * The mft record is then marked dirty and written out asynchronously via the + * vfs inode dirty code path. * * Note the caller clears the page dirty flag before calling ntfs_writepage(). * @@ -875,16 +874,6 @@ BUG_ON(page_has_buffers(page)); BUG_ON(!PageUptodate(page)); - // TODO: Consider using PageWriteback() + unlock_page() in 2.5 once the - // "VM fiddling has ended". Note, don't forget to replace all the - // unlock_page() calls further below with end_page_writeback() ones. - // FIXME: Make sure it is ok to SetPageError() on unlocked page under - // writeback before doing the change! -#if 0 - set_page_writeback(page); - unlock_page(page); -#endif - if (!NInoAttr(ni)) base_ni = ni; else @@ -935,6 +924,14 @@ bytes = PAGE_CACHE_SIZE; /* + * Keep the VM happy. This must be done otherwise the radix-tree tag + * PAGECACHE_TAG_DIRTY remains set even though the page is clean. + */ + BUG_ON(PageWriteback(page)); + set_page_writeback(page); + unlock_page(page); + + /* * Here, we don't need to zero the out of bounds area everytime because * the below memcpy() already takes care of the mmap-at-end-of-file * requirements. If the file is converted to a non-resident one, then @@ -948,7 +945,10 @@ * expose data to userspace/disk which should never have been exposed. * * FIXME: Ensure that i_size increases do the zeroing/overwriting and - * if we cannot guarantee that, then enable the zeroing below. + * if we cannot guarantee that, then enable the zeroing below. If the + * zeroing below is enabled, we MUST move the unlock_page() from above + * to after the kunmap_atomic(), i.e. just before the + * end_page_writeback(). */ kaddr = kmap_atomic(page, KM_USER0); @@ -966,11 +966,10 @@ #endif kunmap_atomic(kaddr, KM_USER0); - unlock_page(page); + end_page_writeback(page); - // TODO: Mark mft record dirty so it gets written back. - ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. " - "Wrote to memory only..."); + /* Mark the mft record dirty, so it gets written back. */ + mark_mft_record_dirty(ctx->ntfs_ino); put_attr_search_ctx(ctx); unmap_mft_record(base_ni); @@ -1022,7 +1021,7 @@ ni = NTFS_I(vi); vol = ni->vol; - ntfs_debug("Entering for inode %li, attribute type 0x%x, page index " + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type, page->index, from, to); @@ -1379,7 +1378,7 @@ struct inode *vi = page->mapping->host; ntfs_inode *ni = NTFS_I(vi); - ntfs_debug("Entering for inode %li, attribute type 0x%x, page index " + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type, page->index, from, to); @@ -1487,7 +1486,7 @@ vi = page->mapping->host; - ntfs_debug("Entering for inode %li, attribute type 0x%x, page index " + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " "0x%lx, from = %u, to = %u.", vi->i_ino, NTFS_I(vi)->type, page->index, from, to); @@ -1583,7 +1582,7 @@ vi = page->mapping->host; ni = NTFS_I(vi); - ntfs_debug("Entering for inode %li, attribute type 0x%x, page index " + ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type, page->index, from, to); @@ -1734,9 +1733,8 @@ } kunmap_atomic(kaddr, KM_USER0); - // TODO: Mark mft record dirty so it gets written back. - ntfs_error(vi->i_sb, "Writing to resident files is not supported yet. " - "Wrote to memory only..."); + /* Mark the mft record dirty, so it gets written back. */ + mark_mft_record_dirty(ctx->ntfs_ino); put_attr_search_ctx(ctx); unmap_mft_record(base_ni); diff -urN linux-2.6.7-rc3/fs/ntfs/attrib.c linux-2.6.7/fs/ntfs/attrib.c --- linux-2.6.7-rc3/fs/ntfs/attrib.c 2004-06-15 23:10:02.202956750 -0700 +++ linux-2.6.7/fs/ntfs/attrib.c 2004-06-15 23:10:40.871584644 -0700 @@ -624,7 +624,7 @@ if (drl[ds].vcn == marker_vcn) { ntfs_debug("Old marker = 0x%llx, replacing " - "with LCN_ENOENT.\n", + "with LCN_ENOENT.", (unsigned long long) drl[ds].lcn); drl[ds].lcn = (LCN)LCN_ENOENT; @@ -1565,7 +1565,7 @@ goto do_next_attr_loop; } ntfs_error(base_ni->vol->sb, "Inode contains corrupt attribute list " - "attribute.\n"); + "attribute."); if (ni != base_ni) { unmap_extent_mft_record(ni); ctx->ntfs_ino = base_ni; diff -urN linux-2.6.7-rc3/fs/ntfs/compress.c linux-2.6.7/fs/ntfs/compress.c --- linux-2.6.7-rc3/fs/ntfs/compress.c 2004-06-15 23:10:02.203956792 -0700 +++ linux-2.6.7/fs/ntfs/compress.c 2004-06-15 23:10:40.934587297 -0700 @@ -433,7 +433,7 @@ goto do_next_tag; return_overflow: - ntfs_error(NULL, "Failed. Returning -EOVERFLOW.\n"); + ntfs_error(NULL, "Failed. Returning -EOVERFLOW."); goto return_error; } @@ -851,7 +851,7 @@ if (err) { ntfs_error(vol->sb, "ntfs_decompress() failed in inode " "0x%lx with error code %i. Skipping " - "this compression block.\n", + "this compression block.", ni->mft_no, -err); /* Release the unfinished pages. */ for (; prev_cur_page < cur_page; prev_cur_page++) { diff -urN linux-2.6.7-rc3/fs/ntfs/dir.c linux-2.6.7/fs/ntfs/dir.c --- linux-2.6.7-rc3/fs/ntfs/dir.c 2004-06-15 23:10:02.205956876 -0700 +++ linux-2.6.7/fs/ntfs/dir.c 2004-06-15 23:10:40.956588223 -0700 @@ -1067,7 +1067,7 @@ ntfs_inode *ndir = NTFS_I(vdir); ntfs_volume *vol = NTFS_SB(sb); MFT_RECORD *m; - INDEX_ROOT *ir; + INDEX_ROOT *ir = NULL; INDEX_ENTRY *ie; INDEX_ALLOCATION *ia; u8 *name = NULL; @@ -1139,9 +1139,29 @@ "inode 0x%lx.", vdir->i_ino); goto err_out; } - /* Get to the index root value (it's been verified in read_inode). */ - ir = (INDEX_ROOT*)((u8*)ctx->attr + - le16_to_cpu(ctx->attr->data.resident.value_offset)); + /* + * Copy the index root attribute value to a buffer so that we can put + * the search context and unmap the mft record before calling the + * filldir() callback. We need to do this because of NFSd which calls + * ->lookup() from its filldir callback() and this causes NTFS to + * deadlock as ntfs_lookup() maps the mft record of the directory and + * we have got it mapped here already. The only solution is for us to + * unmap the mft record here so that a call to ntfs_lookup() is able to + * map the mft record without deadlocking. + */ + rc = le32_to_cpu(ctx->attr->data.resident.value_length); + ir = (INDEX_ROOT*)kmalloc(rc, GFP_NOFS); + if (unlikely(!ir)) { + err = -ENOMEM; + goto err_out; + } + /* Copy the index root value (it has been verified in read_inode). */ + memcpy(ir, (u8*)ctx->attr + + le16_to_cpu(ctx->attr->data.resident.value_offset), rc); + put_attr_search_ctx(ctx); + unmap_mft_record(ndir); + ctx = NULL; + m = NULL; index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length); /* The first index entry. */ ie = (INDEX_ENTRY*)((u8*)&ir->index + @@ -1154,7 +1174,7 @@ for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) { ntfs_debug("In index root, offset 0x%x.", (u8*)ie - (u8*)ir); /* Bounds checks. */ - if (unlikely((u8*)ie < (u8*)ctx->mrec || (u8*)ie + + if (unlikely((u8*)ie < (u8*)ir || (u8*)ie + sizeof(INDEX_ENTRY_HEADER) > index_end || (u8*)ie + le16_to_cpu(ie->key_length) > index_end)) @@ -1169,20 +1189,13 @@ rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ROOT, ir, ie, name, dirent, filldir); if (rc) { - put_attr_search_ctx(ctx); - unmap_mft_record(ndir); + kfree(ir); goto abort; } } - /* - * We are done with the index root and the mft record for that matter. - * We need to release it, otherwise we deadlock on ntfs_attr_iget() - * and/or ntfs_read_page(). - */ - put_attr_search_ctx(ctx); - unmap_mft_record(ndir); - m = NULL; - ctx = NULL; + /* We are done with the index root and can free the buffer. */ + kfree(ir); + ir = NULL; /* If there is no index allocation attribute we are finished. */ if (!NInoIndexAllocPresent(ndir)) goto EOD; @@ -1379,6 +1392,8 @@ ntfs_unmap_page(bmp_page); if (ia_page) ntfs_unmap_page(ia_page); + if (ir) + kfree(ir); if (name) kfree(name); if (ctx) diff -urN linux-2.6.7-rc3/fs/ntfs/inode.c linux-2.6.7/fs/ntfs/inode.c --- linux-2.6.7-rc3/fs/ntfs/inode.c 2004-06-15 23:10:02.208957002 -0700 +++ linux-2.6.7/fs/ntfs/inode.c 2004-06-15 23:10:40.985589444 -0700 @@ -1960,49 +1960,134 @@ return err; } +/** + * ntfs_write_inode - write out a dirty inode + * @vi: inode to write out + * @sync: if true, write out synchronously + * + * Write out a dirty inode to disk including any extent inodes if present. + * + * If @sync is true, commit the inode to disk and wait for io completion. This + * is done using write_mft_record(). + * + * If @sync is false, just schedule the write to happen but do not wait for i/o + * completion. In 2.6 kernels, scheduling usually happens just by virtue of + * marking the page (and in this case mft record) dirty but we do not implement + * this yet as write_mft_record() largely ignores the @sync parameter and + * always performs synchronous writes. + */ void ntfs_write_inode(struct inode *vi, int sync) { ntfs_inode *ni = NTFS_I(vi); +#if 0 + attr_search_context *ctx; +#endif + MFT_RECORD *m; + int err = 0; ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", vi->i_ino); - /* * Dirty attribute inodes are written via their real inodes so just - * clean them here. + * clean them here. TODO: Take care of access time updates. */ if (NInoAttr(ni)) { NInoClearDirty(ni); return; } - - /* Write this base mft record. */ - if (NInoDirty(ni)) { - ntfs_warning(vi->i_sb, "Cleaning dirty inode 0x%lx without " - "writing to disk as this is not yet " - "implemented.", vi->i_ino); - NInoClearDirty(ni); + /* Map, pin, and lock the mft record belonging to the inode. */ + m = map_mft_record(ni); + if (unlikely(IS_ERR(m))) { + err = PTR_ERR(m); + goto err_out; } - +#if 0 + /* Obtain the standard information attribute. */ + ctx = get_attr_search_ctx(ni, m); + if (unlikely(!ctx)) { + err = -ENOMEM; + goto unm_err_out; + } + if (unlikely(!lookup_attr(AT_STANDARD_INFORMATION, NULL, 0, + IGNORE_CASE, 0, NULL, 0, ctx))) { + put_attr_search_ctx(ctx); + err = -ENOENT; + goto unm_err_out; + } + // TODO: Update the access times in the standard information attribute + // which is now in ctx->attr. + // - Probably want to have use sops->dirty_inode() to set a flag that + // we need to update the times here rather than having to blindly do + // it every time. Or even don't do it here at all and do it in + // sops->dirty_inode() instead. Problem with this would be that + // sops->dirty_inode() must be atomic under certain circumstances + // and mapping mft records and such like is not atomic. + // - For atime updates also need to check whether they are enabled in + // the superblock flags. + ntfs_warning(vi->i_sb, "Access time updates not implement yet."); + /* + * We just modified the mft record containing the standard information + * attribute. So need to mark the mft record dirty, too, but we do it + * manually so that mark_inode_dirty() is not called again. + * TODO: Only do this if there was a change in any of the times! + */ + if (!NInoTestSetDirty(ctx->ntfs_ino)) + __set_page_dirty_nobuffers(ctx->ntfs_ino->page); + put_attr_search_ctx(ctx); +#endif + /* Write this base mft record. */ + if (NInoDirty(ni)) + err = write_mft_record(ni, m, sync); /* Write all attached extent mft records. */ down(&ni->extent_lock); if (ni->nr_extents > 0) { - int i; ntfs_inode **extent_nis = ni->ext.extent_ntfs_inos; + int i; + ntfs_debug("Writing %i extent inodes.", ni->nr_extents); for (i = 0; i < ni->nr_extents; i++) { ntfs_inode *tni = extent_nis[i]; if (NInoDirty(tni)) { - ntfs_warning(vi->i_sb, "Cleaning dirty extent " - "inode 0x%lx without writing " - "to disk as this is not yet " - "implemented.", tni->mft_no); - NInoClearDirty(tni); + MFT_RECORD *tm = map_mft_record(tni); + int ret; + + if (unlikely(IS_ERR(tm))) { + if (!err || err == -ENOMEM) + err = PTR_ERR(tm); + continue; + } + ret = write_mft_record(tni, tm, sync); + unmap_mft_record(tni); + if (unlikely(ret)) { + if (!err || err == -ENOMEM) + err = ret; + } } } } up(&ni->extent_lock); + unmap_mft_record(ni); + if (unlikely(err)) + goto err_out; + ntfs_debug("Done."); + return; +#if 0 +unm_err_out: + unmap_mft_record(ni); +#endif +err_out: + if (err == -ENOMEM) { + ntfs_warning(vi->i_sb, "Not enough memory to write inode. " + "Marking the inode dirty again, so the VFS " + "retries later."); + mark_inode_dirty(vi); + } else { + ntfs_error(vi->i_sb, "Failed (error code %i): Marking inode " + "as bad. You should run chkdsk.", -err); + make_bad_inode(vi); + } + return; } #endif /* NTFS_RW */ diff -urN linux-2.6.7-rc3/fs/ntfs/mft.c linux-2.6.7/fs/ntfs/mft.c --- linux-2.6.7-rc3/fs/ntfs/mft.c 2004-06-15 23:10:02.213957213 -0700 +++ linux-2.6.7/fs/ntfs/mft.c 2004-06-15 23:10:41.031591381 -0700 @@ -102,6 +102,13 @@ */ extern int ntfs_readpage(struct file *, struct page *); +#ifdef NTFS_RW +/** + * ntfs_mft_writepage - forward declaration, function is further below + */ +static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc); +#endif /* NTFS_RW */ + /** * ntfs_mft_aops - address space operations for access to $MFT * @@ -112,6 +119,10 @@ .readpage = ntfs_readpage, /* Fill page with data. */ .sync_page = block_sync_page, /* Currently, just unplugs the disk request queue. */ +#ifdef NTFS_RW + .writepage = ntfs_mft_writepage, /* Write out the dirty mft + records in a page. */ +#endif /* NTFS_RW */ }; /** @@ -429,3 +440,654 @@ ntfs_clear_extent_inode(ni); return m; } + +#ifdef NTFS_RW + +/** + * __mark_mft_record_dirty - set the mft record and the page containing it dirty + * @ni: ntfs inode describing the mapped mft record + * + * Internal function. Users should call mark_mft_record_dirty() instead. + * + * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni, + * as well as the page containing the mft record, dirty. Also, mark the base + * vfs inode dirty. This ensures that any changes to the mft record are + * written out to disk. + * + * NOTE: We only set I_DIRTY_SYNC and I_DIRTY_DATASYNC (and not I_DIRTY_PAGES) + * on the base vfs inode, because even though file data may have been modified, + * it is dirty in the inode meta data rather than the data page cache of the + * inode, and thus there are no data pages that need writing out. Therefore, a + * full mark_inode_dirty() is overkill. A mark_inode_dirty_sync(), on the + * other hand, is not sufficient, because I_DIRTY_DATASYNC needs to be set to + * ensure ->write_inode is called from generic_osync_inode() and this needs to + * happen or the file data would not necessarily hit the device synchronously, + * even though the vfs inode has the O_SYNC flag set. Also, I_DIRTY_DATASYNC + * simply "feels" better than just I_DIRTY_SYNC, since the file data has not + * actually hit the block device yet, which is not what I_DIRTY_SYNC on its own + * would suggest. + */ +void __mark_mft_record_dirty(ntfs_inode *ni) +{ + struct page *page = ni->page; + ntfs_inode *base_ni; + + ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); + BUG_ON(!page); + BUG_ON(NInoAttr(ni)); + + /* + * Set the page containing the mft record dirty. This also marks the + * $MFT inode dirty (I_DIRTY_PAGES). + */ + __set_page_dirty_nobuffers(page); + + /* Determine the base vfs inode and mark it dirty, too. */ + down(&ni->extent_lock); + if (likely(ni->nr_extents >= 0)) + base_ni = ni; + else + base_ni = ni->ext.base_ntfs_ino; + up(&ni->extent_lock); + __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC); +} + +static const char *ntfs_please_email = "Please email " + "linux-ntfs-dev@lists.sourceforge.net and say that you saw " + "this message. Thank you."; + +/** + * sync_mft_mirror_umount - synchronise an mft record to the mft mirror + * @ni: ntfs inode whose mft record to synchronize + * @m: mapped, mst protected (extent) mft record to synchronize + * + * Write the mapped, mst protected (extent) mft record @m described by the + * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr) bypassing + * the page cache and the $MFTMirr inode itself. + * + * This function is only for use at umount time when the mft mirror inode has + * already been disposed off. We BUG() if we are called while the mft mirror + * inode is still attached to the volume. + * + * On success return 0. On error return -errno. + * + * NOTE: This function is not implemented yet as I am not convinced it can + * actually be triggered considering the sequence of commits we do in super.c:: + * ntfs_put_super(). But just in case we provide this place holder as the + * alternative would be either to BUG() or to get a NULL pointer dereference + * and Oops. + */ +static int sync_mft_mirror_umount(ntfs_inode *ni, MFT_RECORD *m) +{ + ntfs_volume *vol = ni->vol; + + BUG_ON(vol->mftmirr_ino); + ntfs_error(vol->sb, "Umount time mft mirror syncing is not " + "implemented yet. %s", ntfs_please_email); + return -EOPNOTSUPP; +} + +/** + * sync_mft_mirror - synchronize an mft record to the mft mirror + * @ni: ntfs inode whose mft record to synchronize + * @m: mapped, mst protected (extent) mft record to synchronize + * @sync: if true, wait for i/o completion + * + * Write the mapped, mst protected (extent) mft record @m described by the + * (regular or extent) ntfs inode @ni to the mft mirror ($MFTMirr). + * + * On success return 0. On error return -errno and set the volume errors flag + * in the ntfs_volume to which @ni belongs. + * + * NOTE: We always perform synchronous i/o and ignore the @sync parameter. + * + * TODO: If @sync is false, want to do truly asynchronous i/o, i.e. just + * schedule i/o via ->writepage or do it via kntfsd or whatever. + */ +static int sync_mft_mirror(ntfs_inode *ni, MFT_RECORD *m, int sync) +{ + ntfs_volume *vol = ni->vol; + struct page *page; + unsigned int blocksize = vol->sb->s_blocksize; + int max_bhs = vol->mft_record_size / blocksize; + struct buffer_head *bhs[max_bhs]; + struct buffer_head *bh, *head; + u8 *kmirr; + unsigned int block_start, block_end, m_start, m_end; + int i_bhs, nr_bhs, err = 0; + + ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); + BUG_ON(!max_bhs); + if (unlikely(!vol->mftmirr_ino)) { + /* This could happen during umount... */ + err = sync_mft_mirror_umount(ni, m); + if (likely(!err)) + return err; + goto err_out; + } + /* Get the page containing the mirror copy of the mft record @m. */ + page = ntfs_map_page(vol->mftmirr_ino->i_mapping, ni->mft_no >> + (PAGE_CACHE_SHIFT - vol->mft_record_size_bits)); + if (unlikely(IS_ERR(page))) { + ntfs_error(vol->sb, "Failed to map mft mirror page."); + err = PTR_ERR(page); + goto err_out; + } + /* + * Exclusion against other writers. This should never be a problem + * since the page in which the mft record @m resides is also locked and + * hence any other writers would be held up there but it is better to + * make sure no one is writing from elsewhere. + */ + lock_page(page); + /* The address in the page of the mirror copy of the mft record @m. */ + kmirr = page_address(page) + ((ni->mft_no << vol->mft_record_size_bits) + & ~PAGE_CACHE_MASK); + /* Copy the mst protected mft record to the mirror. */ + memcpy(kmirr, m, vol->mft_record_size); + /* Make sure we have mapped buffers. */ + if (!page_has_buffers(page)) { +no_buffers_err_out: + ntfs_error(vol->sb, "Writing mft mirror records without " + "existing buffers is not implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + goto unlock_err_out; + } + bh = head = page_buffers(page); + if (!bh) + goto no_buffers_err_out; + nr_bhs = 0; + block_start = 0; + m_start = kmirr - (u8*)page_address(page); + m_end = m_start + vol->mft_record_size; + do { + block_end = block_start + blocksize; + /* + * If the buffer is outside the mft record, just skip it, + * clearing it if it is dirty to make sure it is not written + * out. It should never be marked dirty but better be safe. + */ + if ((block_end <= m_start) || (block_start >= m_end)) { + if (buffer_dirty(bh)) { + ntfs_warning(vol->sb, "Clearing dirty mft " + "record page buffer. %s", + ntfs_please_email); + clear_buffer_dirty(bh); + } + continue; + } + if (!buffer_mapped(bh)) { + ntfs_error(vol->sb, "Writing mft mirror records " + "without existing mapped buffers is " + "not implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + continue; + } + if (!buffer_uptodate(bh)) { + ntfs_error(vol->sb, "Writing mft mirror records " + "without existing uptodate buffers is " + "not implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + continue; + } + BUG_ON(!nr_bhs && (m_start != block_start)); + BUG_ON(nr_bhs >= max_bhs); + bhs[nr_bhs++] = bh; + BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end)); + } while (block_start = block_end, (bh = bh->b_this_page) != head); + if (likely(!err)) { + /* Lock buffers and start synchronous write i/o on them. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) { + struct buffer_head *tbh = bhs[i_bhs]; + + if (unlikely(test_set_buffer_locked(tbh))) + BUG(); + BUG_ON(!buffer_uptodate(tbh)); + if (buffer_dirty(tbh)) + clear_buffer_dirty(tbh); + get_bh(tbh); + tbh->b_end_io = end_buffer_write_sync; + submit_bh(WRITE, tbh); + } + /* Wait on i/o completion of buffers. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) { + struct buffer_head *tbh = bhs[i_bhs]; + + wait_on_buffer(tbh); + if (unlikely(!buffer_uptodate(tbh))) { + err = -EIO; + /* + * Set the buffer uptodate so the page & buffer + * states don't become out of sync. + */ + if (PageUptodate(page)) + set_buffer_uptodate(tbh); + } + } + } else /* if (unlikely(err)) */ { + /* Clean the buffers. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) + clear_buffer_dirty(bhs[i_bhs]); + } +unlock_err_out: + /* Current state: all buffers are clean, unlocked, and uptodate. */ + /* Remove the mst protection fixups again. */ + post_write_mst_fixup((NTFS_RECORD*)kmirr); + flush_dcache_page(page); + unlock_page(page); + ntfs_unmap_page(page); + if (unlikely(err)) { + /* I/O error during writing. This is really bad! */ + ntfs_error(vol->sb, "I/O error while writing mft mirror " + "record 0x%lx! You should unmount the volume " + "and run chkdsk or ntfsfix.", ni->mft_no); + goto err_out; + } + ntfs_debug("Done."); + return 0; +err_out: + ntfs_error(vol->sb, "Failed to synchronize $MFTMirr (error code %i). " + "Volume will be left marked dirty on umount. Run " + "ntfsfix on the partition after umounting to correct " + "this.", -err); + /* We don't want to clear the dirty bit on umount. */ + NVolSetErrors(vol); + return err; +} + +/** + * write_mft_record_nolock - write out a mapped (extent) mft record + * @ni: ntfs inode describing the mapped (extent) mft record + * @m: mapped (extent) mft record to write + * @sync: if true, wait for i/o completion + * + * Write the mapped (extent) mft record @m described by the (regular or extent) + * ntfs inode @ni to backing store. If the mft record @m has a counterpart in + * the mft mirror, that is also updated. + * + * On success, clean the mft record and return 0. On error, leave the mft + * record dirty and return -errno. The caller should call make_bad_inode() on + * the base inode to ensure no more access happens to this inode. We do not do + * it here as the caller may want to finish writing other extent mft records + * first to minimize on-disk metadata inconsistencies. + * + * NOTE: We always perform synchronous i/o and ignore the @sync parameter. + * However, if the mft record has a counterpart in the mft mirror and @sync is + * true, we write the mft record, wait for i/o completion, and only then write + * the mft mirror copy. This ensures that if the system crashes either the mft + * or the mft mirror will contain a self-consistent mft record @m. If @sync is + * false on the other hand, we start i/o on both and then wait for completion + * on them. This provides a speedup but no longer guarantees that you will end + * up with a self-consistent mft record in the case of a crash but if you asked + * for asynchronous writing you probably do not care about that anyway. + * + * TODO: If @sync is false, want to do truly asynchronous i/o, i.e. just + * schedule i/o via ->writepage or do it via kntfsd or whatever. + */ +int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync) +{ + ntfs_volume *vol = ni->vol; + struct page *page = ni->page; + unsigned int blocksize = vol->sb->s_blocksize; + int max_bhs = vol->mft_record_size / blocksize; + struct buffer_head *bhs[max_bhs]; + struct buffer_head *bh, *head; + unsigned int block_start, block_end, m_start, m_end; + int i_bhs, nr_bhs, err = 0; + + ntfs_debug("Entering for inode 0x%lx.", ni->mft_no); + BUG_ON(NInoAttr(ni)); + BUG_ON(!max_bhs); + BUG_ON(!page); + BUG_ON(!PageLocked(page)); + /* + * If the ntfs_inode is clean no need to do anything. If it is dirty, + * mark it as clean now so that it can be redirtied later on if needed. + * There is no danger of races as as long as the caller is holding the + * locks for the mft record @m and the page it is in. + */ + if (!NInoTestClearDirty(ni)) + goto done; + /* Make sure we have mapped buffers. */ + if (!page_has_buffers(page)) { +no_buffers_err_out: + ntfs_error(vol->sb, "Writing mft records without existing " + "buffers is not implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + goto err_out; + } + bh = head = page_buffers(page); + if (!bh) + goto no_buffers_err_out; + nr_bhs = 0; + block_start = 0; + m_start = ni->page_ofs; + m_end = m_start + vol->mft_record_size; + do { + block_end = block_start + blocksize; + /* + * If the buffer is outside the mft record, just skip it, + * clearing it if it is dirty to make sure it is not written + * out. It should never be marked dirty but better be safe. + */ + if ((block_end <= m_start) || (block_start >= m_end)) { + if (buffer_dirty(bh)) { + ntfs_warning(vol->sb, "Clearing dirty mft " + "record page buffer. %s", + ntfs_please_email); + clear_buffer_dirty(bh); + } + continue; + } + if (!buffer_mapped(bh)) { + ntfs_error(vol->sb, "Writing mft records without " + "existing mapped buffers is not " + "implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + continue; + } + if (!buffer_uptodate(bh)) { + ntfs_error(vol->sb, "Writing mft records without " + "existing uptodate buffers is not " + "implemented yet. %s", + ntfs_please_email); + err = -EOPNOTSUPP; + continue; + } + BUG_ON(!nr_bhs && (m_start != block_start)); + BUG_ON(nr_bhs >= max_bhs); + bhs[nr_bhs++] = bh; + BUG_ON((nr_bhs >= max_bhs) && (m_end != block_end)); + } while (block_start = block_end, (bh = bh->b_this_page) != head); + if (unlikely(err)) + goto cleanup_out; + /* Apply the mst protection fixups. */ + err = pre_write_mst_fixup((NTFS_RECORD*)m, vol->mft_record_size); + if (err) { + ntfs_error(vol->sb, "Failed to apply mst fixups!"); + goto cleanup_out; + } + flush_dcache_mft_record_page(ni); + /* Lock buffers and start synchronous write i/o on them. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) { + struct buffer_head *tbh = bhs[i_bhs]; + + if (unlikely(test_set_buffer_locked(tbh))) + BUG(); + BUG_ON(!buffer_uptodate(tbh)); + if (buffer_dirty(tbh)) + clear_buffer_dirty(tbh); + get_bh(tbh); + tbh->b_end_io = end_buffer_write_sync; + submit_bh(WRITE, tbh); + } + /* Synchronize the mft mirror now if not @sync. */ + if (!sync && ni->mft_no < vol->mftmirr_size) + sync_mft_mirror(ni, m, sync); + /* Wait on i/o completion of buffers. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) { + struct buffer_head *tbh = bhs[i_bhs]; + + wait_on_buffer(tbh); + if (unlikely(!buffer_uptodate(tbh))) { + err = -EIO; + /* + * Set the buffer uptodate so the page & buffer states + * don't become out of sync. + */ + if (PageUptodate(page)) + set_buffer_uptodate(tbh); + } + } + /* If @sync, now synchronize the mft mirror. */ + if (sync && ni->mft_no < vol->mftmirr_size) + sync_mft_mirror(ni, m, sync); + /* Remove the mst protection fixups again. */ + post_write_mst_fixup((NTFS_RECORD*)m); + flush_dcache_mft_record_page(ni); + if (unlikely(err)) { + /* I/O error during writing. This is really bad! */ + ntfs_error(vol->sb, "I/O error while writing mft record " + "0x%lx! Marking base inode as bad. You " + "should unmount the volume and run chkdsk.", + ni->mft_no); + goto err_out; + } +done: + ntfs_debug("Done."); + return 0; +cleanup_out: + /* Clean the buffers. */ + for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) + clear_buffer_dirty(bhs[i_bhs]); +err_out: + /* + * Current state: all buffers are clean, unlocked, and uptodate. + * The caller should mark the base inode as bad so that no more i/o + * happens. ->clear_inode() will still be invoked so all extent inodes + * and other allocated memory will be freed. + */ + if (err == -ENOMEM) { + ntfs_error(vol->sb, "Not enough memory to write mft record. " + "Redirtying so the write is retried later."); + mark_mft_record_dirty(ni); + err = 0; + } + return err; +} + +/** + * ntfs_mft_writepage - check if a metadata page contains dirty mft records + * @page: metadata page possibly containing dirty mft records + * @wbc: writeback control structure + * + * This is called from the VM when it wants to have a dirty $MFT/$DATA metadata + * page cache page cleaned. The VM has already locked the page and marked it + * clean. Instead of writing the page as a conventional ->writepage function + * would do, we check if the page still contains any dirty mft records (it must + * have done at some point in the past since the page was marked dirty) and if + * none are found, i.e. all mft records are clean, we unlock the page and + * return. The VM is then free to do with the page as it pleases. If on the + * other hand we do find any dirty mft records in the page, we redirty the page + * before unlocking it and returning so the VM knows that the page is still + * busy and cannot be thrown out. + * + * Note, we do not actually write any dirty mft records here because they are + * dirty inodes and hence will be written by the VFS inode dirty code paths. + * There is no need to write them from the VM page dirty code paths, too and in + * fact once we implement journalling it would be a complete nightmare having + * two code paths leading to mft record writeout. + */ +static int ntfs_mft_writepage(struct page *page, struct writeback_control *wbc) +{ + struct inode *mft_vi = page->mapping->host; + struct super_block *sb = mft_vi->i_sb; + ntfs_volume *vol = NTFS_SB(sb); + u8 *maddr; + MFT_RECORD *m; + ntfs_inode **extent_nis; + unsigned long mft_no; + int nr, i, j; + BOOL is_dirty = FALSE; + + BUG_ON(mft_vi != vol->mft_ino); + /* The first mft record number in the page. */ + mft_no = page->index << (PAGE_CACHE_SHIFT - vol->mft_record_size_bits); + /* Number of mft records in the page. */ + nr = PAGE_CACHE_SIZE >> vol->mft_record_size_bits; + BUG_ON(!nr); + ntfs_debug("Entering for %i inodes starting at 0x%lx.", nr, mft_no); + /* Iterate over the mft records in the page looking for a dirty one. */ + maddr = (u8*)kmap(page); + for (i = 0; i < nr; ++i, ++mft_no, maddr += vol->mft_record_size) { + struct inode *vi; + ntfs_inode *ni, *eni; + ntfs_attr na; + + na.mft_no = mft_no; + na.name = NULL; + na.name_len = 0; + na.type = AT_UNUSED; + /* + * Check if the inode corresponding to this mft record is in + * the VFS inode cache and obtain a reference to it if it is. + */ + ntfs_debug("Looking for inode 0x%lx in icache.", mft_no); + /* + * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from + * here or we deadlock because the inode is already locked by + * the kernel (fs/fs-writeback.c::__sync_single_inode()) and + * ilookup5() waits until the inode is unlocked before + * returning it and it never gets unlocked because + * ntfs_mft_writepage() never returns. )-: Fortunately, we + * have inode 0 pinned in icache for the duration of the mount + * so we can access it directly. + */ + if (!mft_no) { + /* Balance the below iput(). */ + vi = igrab(mft_vi); + BUG_ON(vi != mft_vi); + } else + vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na); + if (vi) { + ntfs_debug("Inode 0x%lx is in icache.", mft_no); + /* The inode is in icache. Check if it is dirty. */ + ni = NTFS_I(vi); + if (!NInoDirty(ni)) { + /* The inode is not dirty, skip this record. */ + ntfs_debug("Inode 0x%lx is not dirty, " + "continuing search.", mft_no); + iput(vi); + continue; + } + ntfs_debug("Inode 0x%lx is dirty, aborting search.", + mft_no); + /* The inode is dirty, no need to search further. */ + iput(vi); + is_dirty = TRUE; + break; + } + ntfs_debug("Inode 0x%lx is not in icache.", mft_no); + /* The inode is not in icache. */ + /* Skip the record if it is not a mft record (type "FILE"). */ + if (!ntfs_is_mft_recordp(maddr)) { + ntfs_debug("Mft record 0x%lx is not a FILE record, " + "continuing search.", mft_no); + continue; + } + m = (MFT_RECORD*)maddr; + /* + * Skip the mft record if it is not in use. FIXME: What about + * deleted/deallocated (extent) inodes? (AIA) + */ + if (!(m->flags & MFT_RECORD_IN_USE)) { + ntfs_debug("Mft record 0x%lx is not in use, " + "continuing search.", mft_no); + continue; + } + /* Skip the mft record if it is a base inode. */ + if (!m->base_mft_record) { + ntfs_debug("Mft record 0x%lx is a base record, " + "continuing search.", mft_no); + continue; + } + /* + * This is an extent mft record. Check if the inode + * corresponding to its base mft record is in icache. + */ + na.mft_no = MREF_LE(m->base_mft_record); + ntfs_debug("Mft record 0x%lx is an extent record. Looking " + "for base inode 0x%lx in icache.", mft_no, + na.mft_no); + vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode, + &na); + if (!vi) { + /* + * The base inode is not in icache. Skip this extent + * mft record. + */ + ntfs_debug("Base inode 0x%lx is not in icache, " + "continuing search.", na.mft_no); + continue; + } + ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no); + /* + * The base inode is in icache. Check if it has the extent + * inode corresponding to this extent mft record attached. + */ + ni = NTFS_I(vi); + down(&ni->extent_lock); + if (ni->nr_extents <= 0) { + /* + * The base inode has no attached extent inodes. Skip + * this extent mft record. + */ + up(&ni->extent_lock); + iput(vi); + continue; + } + /* Iterate over the attached extent inodes. */ + extent_nis = ni->ext.extent_ntfs_inos; + for (eni = NULL, j = 0; j < ni->nr_extents; ++j) { + if (mft_no == extent_nis[j]->mft_no) { + /* + * Found the extent inode corresponding to this + * extent mft record. + */ + eni = extent_nis[j]; + break; + } + } + /* + * If the extent inode was not attached to the base inode, skip + * this extent mft record. + */ + if (!eni) { + up(&ni->extent_lock); + iput(vi); + continue; + } + /* + * Found the extent inode corrsponding to this extent mft + * record. If it is dirty, no need to search further. + */ + if (NInoDirty(eni)) { + up(&ni->extent_lock); + iput(vi); + is_dirty = TRUE; + break; + } + /* The extent inode is not dirty, so do the next record. */ + up(&ni->extent_lock); + iput(vi); + } + kunmap(page); + /* If a dirty mft record was found, redirty the page. */ + if (is_dirty) { + ntfs_debug("Inode 0x%lx is dirty. Redirtying the page " + "starting at inode 0x%lx.", mft_no, + page->index << (PAGE_CACHE_SHIFT - + vol->mft_record_size_bits)); + redirty_page_for_writepage(wbc, page); + unlock_page(page); + } else { + /* + * Keep the VM happy. This must be done otherwise the + * radix-tree tag PAGECACHE_TAG_DIRTY remains set even though + * the page is clean. + */ + BUG_ON(PageWriteback(page)); + set_page_writeback(page); + unlock_page(page); + end_page_writeback(page); + } + ntfs_debug("Done."); + return 0; +} + +#endif /* NTFS_RW */ diff -urN linux-2.6.7-rc3/fs/ntfs/mft.h linux-2.6.7/fs/ntfs/mft.h --- linux-2.6.7-rc3/fs/ntfs/mft.h 2004-06-15 23:10:02.213957213 -0700 +++ linux-2.6.7/fs/ntfs/mft.h 2004-06-15 23:10:41.032591423 -0700 @@ -57,6 +57,60 @@ flush_dcache_page(ni->page); } +extern void __mark_mft_record_dirty(ntfs_inode *ni); + +/** + * mark_mft_record_dirty - set the mft record and the page containing it dirty + * @ni: ntfs inode describing the mapped mft record + * + * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni, + * as well as the page containing the mft record, dirty. Also, mark the base + * vfs inode dirty. This ensures that any changes to the mft record are + * written out to disk. + * + * NOTE: Do not do anything if the mft record is already marked dirty. + */ +static inline void mark_mft_record_dirty(ntfs_inode *ni) +{ + if (!NInoTestSetDirty(ni)) + __mark_mft_record_dirty(ni); +} + +extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync); + +/** + * write_mft_record - write out a mapped (extent) mft record + * @ni: ntfs inode describing the mapped (extent) mft record + * @m: mapped (extent) mft record to write + * @sync: if true, wait for i/o completion + * + * This is just a wrapper for write_mft_record_nolock() (see mft.c), which + * locks the page for the duration of the write. This ensures that there are + * no race conditions between writing the mft record via the dirty inode code + * paths and via the page cache write back code paths or between writing + * neighbouring mft records residing in the same page. + * + * Locking the page also serializes us against ->readpage() if the page is not + * uptodate. + * + * On success, clean the mft record and return 0. On error, leave the mft + * record dirty and return -errno. The caller should call make_bad_inode() on + * the base inode to ensure no more access happens to this inode. We do not do + * it here as the caller may want to finish writing other extent mft records + * first to minimize on-disk metadata inconsistencies. + */ +static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync) +{ + struct page *page = ni->page; + int err; + + BUG_ON(!page); + lock_page(page); + err = write_mft_record_nolock(ni, m, sync); + unlock_page(page); + return err; +} + #endif /* NTFS_RW */ #endif /* _LINUX_NTFS_MFT_H */ diff -urN linux-2.6.7-rc3/fs/ntfs/super.c linux-2.6.7/fs/ntfs/super.c --- linux-2.6.7-rc3/fs/ntfs/super.c 2004-06-15 23:10:02.217957381 -0700 +++ linux-2.6.7/fs/ntfs/super.c 2004-06-15 23:10:41.036591592 -0700 @@ -291,6 +291,101 @@ return FALSE; } +#ifdef NTFS_RW + +/** + * ntfs_write_volume_flags - write new flags to the volume information flags + * @vol: ntfs volume on which to modify the flags + * @flags: new flags value for the volume information flags + * + * Internal function. You probably want to use ntfs_{set,clear}_volume_flags() + * instead (see below). + * + * Replace the volume information flags on the volume @vol with the value + * supplied in @flags. Note, this overwrites the volume information flags, so + * make sure to combine the flags you want to modify with the old flags and use + * the result when calling ntfs_write_volume_flags(). + * + * Return 0 on success and -errno on error. + */ +static int ntfs_write_volume_flags(ntfs_volume *vol, const VOLUME_FLAGS flags) +{ + ntfs_inode *ni = NTFS_I(vol->vol_ino); + MFT_RECORD *m; + VOLUME_INFORMATION *vi; + attr_search_context *ctx; + int err; + + ntfs_debug("Entering, old flags = 0x%x, new flags = 0x%x.", + vol->vol_flags, flags); + if (vol->vol_flags == flags) + goto done; + BUG_ON(!ni); + m = map_mft_record(ni); + if (IS_ERR(m)) { + err = PTR_ERR(m); + goto err_out; + } + ctx = get_attr_search_ctx(ni, m); + if (!ctx) { + err = -ENOMEM; + goto put_unm_err_out; + } + if (!lookup_attr(AT_VOLUME_INFORMATION, NULL, 0, 0, 0, NULL, 0, ctx)) { + err = -EIO; + goto put_unm_err_out; + } + vi = (VOLUME_INFORMATION*)((u8*)ctx->attr + + le16_to_cpu(ctx->attr->data.resident.value_offset)); + vol->vol_flags = vi->flags = flags; + flush_dcache_mft_record_page(ctx->ntfs_ino); + mark_mft_record_dirty(ctx->ntfs_ino); + put_attr_search_ctx(ctx); + unmap_mft_record(ni); +done: + ntfs_debug("Done."); + return 0; +put_unm_err_out: + if (ctx) + put_attr_search_ctx(ctx); + unmap_mft_record(ni); +err_out: + ntfs_error(vol->sb, "Failed with error code %i.", -err); + return err; +} + +/** + * ntfs_set_volume_flags - set bits in the volume information flags + * @vol: ntfs volume on which to modify the flags + * @flags: flags to set on the volume + * + * Set the bits in @flags in the volume information flags on the volume @vol. + * + * Return 0 on success and -errno on error. + */ +static inline int ntfs_set_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags) +{ + flags &= VOLUME_FLAGS_MASK; + return ntfs_write_volume_flags(vol, vol->vol_flags | flags); +} + +/** + * ntfs_clear_volume_flags - clear bits in the volume information flags + * @vol: ntfs volume on which to modify the flags + * @flags: flags to clear on the volume + * + * Clear the bits in @flags in the volume information flags on the volume @vol. + * + * Return 0 on success and -errno on error. + */ +static inline int ntfs_clear_volume_flags(ntfs_volume *vol, VOLUME_FLAGS flags) +{ + flags &= VOLUME_FLAGS_MASK; + return ntfs_write_volume_flags(vol, vol->vol_flags & ~flags); +} + +#endif /* NTFS_RW */ + /** * ntfs_remount - change the mount options of a mounted ntfs filesystem * @sb: superblock of mounted ntfs filesystem @@ -316,30 +411,72 @@ * For the read-write compiled driver, if we are remounting read-write, * make sure there are no volume errors and that no unsupported volume * flags are set. Also, empty the logfile journal as it would become - * stale as soon as something is written to the volume. + * stale as soon as something is written to the volume and mark the + * volume dirty so that chkdsk is run if the volume is not umounted + * cleanly. + * + * When remounting read-only, mark the volume clean if no volume errors + * have occured. */ if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { static const char *es = ". Cannot remount read-write."; + /* Remounting read-write. */ if (NVolErrors(vol)) { ntfs_error(sb, "Volume has errors and is read-only%s", es); return -EROFS; } + if (vol->vol_flags & VOLUME_IS_DIRTY) { + ntfs_error(sb, "Volume is dirty and read-only%s", es); + return -EROFS; + } if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { ntfs_error(sb, "Volume has unsupported flags set and " "is read-only%s", es); return -EROFS; } + if (ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { + ntfs_error(sb, "Failed to set dirty bit in volume " + "information flags%s", es); + return -EROFS; + } +#if 0 + // TODO: Enable this code once we start modifying anything that + // is different between NTFS 1.2 and 3.x... + /* Set NT4 compatibility flag on newer NTFS version volumes. */ + if ((vol->major_ver > 1)) { + if (ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) { + ntfs_error(sb, "Failed to set NT4 " + "compatibility flag%s", es); + NVolSetErrors(vol); + return -EROFS; + } + } +#endif if (!ntfs_empty_logfile(vol->logfile_ino)) { ntfs_error(sb, "Failed to empty journal $LogFile%s", es); NVolSetErrors(vol); return -EROFS; } + } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { + /* Remounting read-only. */ + if (!NVolErrors(vol)) { + if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) + ntfs_warning(sb, "Failed to clear dirty bit " + "in volume information " + "flags. Run chkdsk."); + } } // TODO: For now we enforce no atime and dir atime updates as they are // not implemented. + if ((sb->s_flags & MS_NOATIME) && !(*flags & MS_NOATIME)) + ntfs_warning(sb, "Atime updates are not implemented yet. " + "Leaving them disabled."); + else if ((sb->s_flags & MS_NODIRATIME) && !(*flags & MS_NODIRATIME)) + ntfs_warning(sb, "Directory atime updates are not implemented " + "yet. Leaving them disabled."); *flags |= MS_NOATIME | MS_NODIRATIME; #endif /* ! NTFS_RW */ @@ -1131,7 +1268,7 @@ le32_to_cpu(ctx->attr->data.resident.value_length) > (u8*)ctx->attr + le32_to_cpu(ctx->attr->length)) goto err_put_vol; - /* Setup volume flags and version. */ + /* Copy the volume flags and version to the ntfs_volume structure. */ vol->vol_flags = vi->flags; vol->major_ver = vi->major_ver; vol->minor_ver = vi->minor_ver; @@ -1142,9 +1279,12 @@ #ifdef NTFS_RW /* Make sure that no unsupported volume flags are set. */ if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { - static const char *es1 = "Volume has unsupported flags set"; + static const char *es1a = "Volume is dirty"; + static const char *es1b = "Volume has unsupported flags set"; static const char *es2 = ". Run chkdsk and mount in Windows."; - + const char *es1; + + es1 = vol->vol_flags & VOLUME_IS_DIRTY ? es1a : es1b; /* If a read-write mount, convert it to a read-only mount. */ if (!(sb->s_flags & MS_RDONLY)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | @@ -1171,10 +1311,12 @@ */ if (!load_and_check_logfile(vol) || !ntfs_is_logfile_clean(vol->logfile_ino)) { - static const char *es1 = "Failed to load $LogFile"; - static const char *es2 = "$LogFile is not clean"; - static const char *es3 = ". Mount in Windows."; + static const char *es1a = "Failed to load $LogFile"; + static const char *es1b = "$LogFile is not clean"; + static const char *es2 = ". Mount in Windows."; + const char *es1; + es1 = !vol->logfile_ino ? es1a : es1b; /* If a read-write mount, convert it to a read-only mount. */ if (!(sb->s_flags & MS_RDONLY)) { if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | @@ -1182,21 +1324,66 @@ ntfs_error(sb, "%s and neither on_errors=" "continue nor on_errors=" "remount-ro was specified%s", - !vol->logfile_ino ? es1 : es2, - es3); + es1, es2); goto iput_logfile_err_out; } sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; - ntfs_error(sb, "%s. Mounting read-only%s", - !vol->logfile_ino ? es1 : es2, es3); + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); } else ntfs_warning(sb, "%s. Will not be able to remount " - "read-write%s", - !vol->logfile_ino ? es1 : es2, es3); + "read-write%s", es1, es2); /* This will prevent a read-write remount. */ NVolSetErrors(vol); - /* If a read-write mount, empty the logfile. */ - } else if (!(sb->s_flags & MS_RDONLY) && + } + /* If (still) a read-write mount, mark the volume dirty. */ + if (!(sb->s_flags & MS_RDONLY) && + ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { + static const char *es1 = "Failed to set dirty bit in volume " + "information flags"; + static const char *es2 = ". Run chkdsk."; + + /* Convert to a read-only mount. */ + if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | + ON_ERRORS_CONTINUE))) { + ntfs_error(sb, "%s and neither on_errors=continue nor " + "on_errors=remount-ro was specified%s", + es1, es2); + goto iput_logfile_err_out; + } + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + /* + * Do not set NVolErrors() because ntfs_remount() might manage + * to set the dirty flag in which case all would be well. + */ + } +#if 0 + // TODO: Enable this code once we start modifying anything that is + // different between NTFS 1.2 and 3.x... + /* + * If (still) a read-write mount, set the NT4 compatibility flag on + * newer NTFS version volumes. + */ + if (!(sb->s_flags & MS_RDONLY) && (vol->major_ver > 1) && + ntfs_set_volume_flags(vol, VOLUME_MOUNTED_ON_NT4)) { + static const char *es1 = "Failed to set NT4 compatibility flag"; + static const char *es2 = ". Run chkdsk."; + + /* Convert to a read-only mount. */ + if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | + ON_ERRORS_CONTINUE))) { + ntfs_error(sb, "%s and neither on_errors=continue nor " + "on_errors=remount-ro was specified%s", + es1, es2); + goto iput_logfile_err_out; + } + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; + NVolSetErrors(vol); + } +#endif + /* If (still) a read-write mount, empty the logfile. */ + if (!(sb->s_flags & MS_RDONLY) && !ntfs_empty_logfile(vol->logfile_ino)) { static const char *es1 = "Failed to empty $LogFile"; static const char *es2 = ". Mount in Windows."; @@ -1209,12 +1396,11 @@ es1, es2); goto iput_logfile_err_out; } - sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); - /* This will prevent a read-write remount. */ + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; NVolSetErrors(vol); } -#endif +#endif /* NTFS_RW */ /* * Get the inode for the attribute definitions file and parse the * attribute definitions. @@ -1289,18 +1475,69 @@ /** * ntfs_put_super - called by the vfs to unmount a volume - * @vfs_sb: vfs superblock of volume to unmount + * @sb: vfs superblock of volume to unmount * * ntfs_put_super() is called by the VFS (from fs/super.c::do_umount()) when * the volume is being unmounted (umount system call has been invoked) and it * releases all inodes and memory belonging to the NTFS specific part of the * super block. */ -static void ntfs_put_super(struct super_block *vfs_sb) +static void ntfs_put_super(struct super_block *sb) { - ntfs_volume *vol = NTFS_SB(vfs_sb); + ntfs_volume *vol = NTFS_SB(sb); ntfs_debug("Entering."); +#ifdef NTFS_RW + /* + * Commit all inodes while they are still open in case some of them + * cause others to be dirtied. + */ + ntfs_commit_inode(vol->vol_ino); + + /* NTFS 3.0+ specific. */ + if (vol->major_ver >= 3) { + if (vol->secure_ino) + ntfs_commit_inode(vol->secure_ino); + } + + ntfs_commit_inode(vol->root_ino); + + down_write(&vol->lcnbmp_lock); + ntfs_commit_inode(vol->lcnbmp_ino); + up_write(&vol->lcnbmp_lock); + + down_write(&vol->mftbmp_lock); + ntfs_commit_inode(vol->mftbmp_ino); + up_write(&vol->mftbmp_lock); + + if (vol->logfile_ino) + ntfs_commit_inode(vol->logfile_ino); + + if (vol->mftmirr_ino) + ntfs_commit_inode(vol->mftmirr_ino); + ntfs_commit_inode(vol->mft_ino); + + /* + * If a read-write mount and no volume errors have occured, mark the + * volume clean. Also, re-commit all affected inodes. + */ + if (!(sb->s_flags & MS_RDONLY)) { + if (!NVolErrors(vol)) { + if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) + ntfs_warning(sb, "Failed to clear dirty bit " + "in volume information " + "flags. Run chkdsk."); + ntfs_commit_inode(vol->vol_ino); + ntfs_commit_inode(vol->root_ino); + if (vol->mftmirr_ino) + ntfs_commit_inode(vol->mftmirr_ino); + ntfs_commit_inode(vol->mft_ino); + } else { + ntfs_warning(sb, "Volume has errors. Leaving volume " + "marked dirty. Run chkdsk."); + } + } +#endif /* NTFS_RW */ iput(vol->vol_ino); vol->vol_ino = NULL; @@ -1331,11 +1568,47 @@ iput(vol->logfile_ino); vol->logfile_ino = NULL; } - if (vol->mftmirr_ino) { + /* Re-commit the mft mirror and mft just in case. */ + ntfs_commit_inode(vol->mftmirr_ino); + ntfs_commit_inode(vol->mft_ino); iput(vol->mftmirr_ino); vol->mftmirr_ino = NULL; } + /* + * If any dirty inodes are left, throw away all mft data page cache + * pages to allow a clean umount. This should never happen any more + * due to mft.c::ntfs_mft_writepage() cleaning all the dirty pages as + * the underlying mft records are written out and cleaned. If it does, + * happen anyway, we want to know... + */ + ntfs_commit_inode(vol->mft_ino); + write_inode_now(vol->mft_ino, 1); + if (!list_empty(&sb->s_dirty)) { + const char *s1, *s2; + + down(&vol->mft_ino->i_sem); + truncate_inode_pages(vol->mft_ino->i_mapping, 0); + up(&vol->mft_ino->i_sem); + write_inode_now(vol->mft_ino, 1); + if (!list_empty(&sb->s_dirty)) { + static const char *_s1 = "inodes"; + static const char *_s2 = ""; + s1 = _s1; + s2 = _s2; + } else { + static const char *_s1 = "mft pages"; + static const char *_s2 = "They have been thrown " + "away. "; + s1 = _s1; + s2 = _s2; + } + ntfs_error(sb, "Dirty %s found at umount time. %sYou should " + "run chkdsk. Please email " + "linux-ntfs-dev@lists.sourceforge.net and say " + "that you saw this message. Thank you.", s1, + s2); + } #endif /* NTFS_RW */ iput(vol->mft_ino); @@ -1344,7 +1617,7 @@ vol->upcase_len = 0; /* * Decrease the number of mounts and destroy the global default upcase - * table if necessary. Also decrease the number of upcase users if we + * table if necessary. Also decrease the number of upcase users if we * are a user. */ down(&ntfs_lock); @@ -1368,7 +1641,7 @@ unload_nls(vol->nls_map); vol->nls_map = NULL; } - vfs_sb->s_fs_info = NULL; + sb->s_fs_info = NULL; kfree(vol); return; } @@ -1629,8 +1902,8 @@ #ifdef NTFS_RW //.dirty_inode = NULL, /* VFS: Called from // __mark_inode_dirty(). */ - //.write_inode = NULL, /* VFS: Write dirty inode to - // disk. */ + .write_inode = ntfs_write_inode, /* VFS: Write dirty inode to + disk. */ //.drop_inode = NULL, /* VFS: Called just after the // inode reference count has // been decreased to zero. @@ -1719,8 +1992,12 @@ #ifndef NTFS_RW sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; #else - // TODO: For now we enforce no atime and dir atime updates as they are - // not implemented. + if (!(sb->s_flags & MS_NOATIME)) + ntfs_warning(sb, "Atime updates are not implemented yet. " + "Disabling them."); + else if (!(sb->s_flags & MS_NODIRATIME)) + ntfs_warning(sb, "Directory atime updates are not implemented " + "yet. Disabling them."); sb->s_flags |= MS_NOATIME | MS_NODIRATIME; #endif /* Allocate a new ntfs_volume and place it in sb->s_fs_info. */ diff -urN linux-2.6.7-rc3/fs/stat.c linux-2.6.7/fs/stat.c --- linux-2.6.7-rc3/fs/stat.c 2004-06-15 23:10:02.260959191 -0700 +++ linux-2.6.7/fs/stat.c 2004-06-15 23:10:41.485610498 -0700 @@ -131,6 +131,8 @@ tmp.st_ino = stat->ino; tmp.st_mode = stat->mode; tmp.st_nlink = stat->nlink; + if (tmp.st_nlink != stat->nlink) + return -EOVERFLOW; SET_UID(tmp.st_uid, stat->uid); SET_GID(tmp.st_gid, stat->gid); tmp.st_rdev = old_encode_dev(stat->rdev); @@ -199,6 +201,8 @@ tmp.st_ino = stat->ino; tmp.st_mode = stat->mode; tmp.st_nlink = stat->nlink; + if (tmp.st_nlink != stat->nlink) + return -EOVERFLOW; SET_UID(tmp.st_uid, stat->uid); SET_GID(tmp.st_gid, stat->gid); #if BITS_PER_LONG == 32 diff -urN linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/io.h linux-2.6.7/include/asm-arm/arch-ebsa110/io.h --- linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/io.h 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-ebsa110/io.h 2004-06-15 23:10:43.362689537 -0700 @@ -50,7 +50,7 @@ #define writew(v,b) __writew(v,b) #define writel(v,b) __writel(v,b) -#define __arch_ioremap(cookie,sz,c) ((void *)(cookie)) +#define __arch_ioremap(cookie,sz,c,a) ((void *)(cookie)) #define __arch_iounmap(cookie) do { } while (0) #endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/system.h linux-2.6.7/include/asm-arm/arch-ebsa110/system.h --- linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/system.h 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-ebsa110/system.h 2004-06-15 23:10:43.363689579 -0700 @@ -25,13 +25,13 @@ const char *irq_stat = (char *)0xff000000; /* disable clock switching */ - asm volatile ("mcr%? p15, 0, ip, c15, c2, 2"); + asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc"); /* wait for an interrupt to occur */ while (!*irq_stat); /* enable clock switching */ - asm volatile ("mcr%? p15, 0, ip, c15, c1, 2"); + asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); } #define arch_reset(mode) cpu_reset(0x80000000) diff -urN linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/timex.h linux-2.6.7/include/asm-arm/arch-ebsa110/timex.h --- linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/timex.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-ebsa110/timex.h 2004-06-15 23:10:43.363689579 -0700 @@ -15,5 +15,5 @@ * This is therefore not used to calculate the * divisor. */ -//#define CLOCK_TICK_RATE 2000000 +#define CLOCK_TICK_RATE 47894000 diff -urN linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/uncompress.h linux-2.6.7/include/asm-arm/arch-ebsa110/uncompress.h --- linux-2.6.7-rc3/include/asm-arm/arch-ebsa110/uncompress.h 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-ebsa110/uncompress.h 2004-06-15 23:10:43.364689621 -0700 @@ -13,26 +13,26 @@ */ static void puts(const char *s) { - __asm__ __volatile__(" - ldrb %0, [%2], #1 - teq %0, #0 - beq 3f -1: strb %0, [%3] -2: ldrb %1, [%3, #0x14] - and %1, %1, #0x60 - teq %1, #0x60 - bne 2b - teq %0, #'\n' - moveq %0, #'\r' - beq 1b - ldrb %0, [%2], #1 - teq %0, #0 - bne 1b -3: ldrb %1, [%3, #0x14] - and %1, %1, #0x60 - teq %1, #0x60 - bne 3b - " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc"); + __asm__ __volatile__( + "ldrb %0, [%2], #1\n" +" teq %0, #0\n" +" beq 3f\n" +"1: strb %0, [%3]\n" +"2: ldrb %1, [%3, #0x14]\n" +" and %1, %1, #0x60\n" +" teq %1, #0x60\n" +" bne 2b\n" +" teq %0, #'\n'\n" +" moveq %0, #'\r'\n" +" beq 1b\n" +" ldrb %0, [%2], #1\n" +" teq %0, #0\n" +" bne 1b\n" +"3: ldrb %1, [%3, #0x14]\n" +" and %1, %1, #0x60\n" +" teq %1, #0x60\n" +" bne 3b" + : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc"); } /* diff -urN linux-2.6.7-rc3/include/asm-arm/arch-lh7a40x/hardware.h linux-2.6.7/include/asm-arm/arch-lh7a40x/hardware.h --- linux-2.6.7-rc3/include/asm-arm/arch-lh7a40x/hardware.h 2004-06-15 23:10:02.391964705 -0700 +++ linux-2.6.7/include/asm-arm/arch-lh7a40x/hardware.h 2004-06-15 23:10:43.599699517 -0700 @@ -37,10 +37,10 @@ # define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2] # define __REG(x) __REGP(io_p2v(x)) typedef struct { volatile u16 offset[4096]; } __regbase16; -# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>2] +# define __REGP16(x) ((__regbase16 *)((x)&~4095))->offset[((x)&4095)>>1] # define __REG16(x) __REGP16(io_p2v(x)) typedef struct { volatile u8 offset[4096]; } __regbase8; -# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[((x)&4095)>>2] +# define __REGP8(x) ((__regbase8 *)((x)&~4095))->offset[(x)&4095] # define __REG8(x) __REGP8(io_p2v(x)) #endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/board-innovator.h linux-2.6.7/include/asm-arm/arch-omap/board-innovator.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/board-innovator.h 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/board-innovator.h 2004-06-15 23:10:43.716704443 -0700 @@ -33,74 +33,74 @@ * OMAP-1510 FPGA * --------------------------------------------------------------------------- */ -#define OMAP1510P1_FPGA_BASE 0xE8000000 /* Virtual */ -#define OMAP1510P1_FPGA_SIZE SZ_4K -#define OMAP1510P1_FPGA_START 0x08000000 /* Physical */ +#define OMAP1510_FPGA_BASE 0xE8000000 /* Virtual */ +#define OMAP1510_FPGA_SIZE SZ_4K +#define OMAP1510_FPGA_START 0x08000000 /* Physical */ /* Revision */ -#define OMAP1510P1_FPGA_REV_LOW (OMAP1510P1_FPGA_BASE + 0x0) -#define OMAP1510P1_FPGA_REV_HIGH (OMAP1510P1_FPGA_BASE + 0x1) +#define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0) +#define OMAP1510_FPGA_REV_HIGH (OMAP1510_FPGA_BASE + 0x1) -#define OMAP1510P1_FPGA_LCD_PANEL_CONTROL (OMAP1510P1_FPGA_BASE + 0x2) -#define OMAP1510P1_FPGA_LED_DIGIT (OMAP1510P1_FPGA_BASE + 0x3) -#define INNOVATOR_FPGA_HID_SPI (OMAP1510P1_FPGA_BASE + 0x4) -#define OMAP1510P1_FPGA_POWER (OMAP1510P1_FPGA_BASE + 0x5) +#define OMAP1510_FPGA_LCD_PANEL_CONTROL (OMAP1510_FPGA_BASE + 0x2) +#define OMAP1510_FPGA_LED_DIGIT (OMAP1510_FPGA_BASE + 0x3) +#define INNOVATOR_FPGA_HID_SPI (OMAP1510_FPGA_BASE + 0x4) +#define OMAP1510_FPGA_POWER (OMAP1510_FPGA_BASE + 0x5) /* Interrupt status */ -#define OMAP1510P1_FPGA_ISR_LO (OMAP1510P1_FPGA_BASE + 0x6) -#define OMAP1510P1_FPGA_ISR_HI (OMAP1510P1_FPGA_BASE + 0x7) +#define OMAP1510_FPGA_ISR_LO (OMAP1510_FPGA_BASE + 0x6) +#define OMAP1510_FPGA_ISR_HI (OMAP1510_FPGA_BASE + 0x7) /* Interrupt mask */ -#define OMAP1510P1_FPGA_IMR_LO (OMAP1510P1_FPGA_BASE + 0x8) -#define OMAP1510P1_FPGA_IMR_HI (OMAP1510P1_FPGA_BASE + 0x9) +#define OMAP1510_FPGA_IMR_LO (OMAP1510_FPGA_BASE + 0x8) +#define OMAP1510_FPGA_IMR_HI (OMAP1510_FPGA_BASE + 0x9) /* Reset registers */ -#define OMAP1510P1_FPGA_HOST_RESET (OMAP1510P1_FPGA_BASE + 0xa) -#define OMAP1510P1_FPGA_RST (OMAP1510P1_FPGA_BASE + 0xb) +#define OMAP1510_FPGA_HOST_RESET (OMAP1510_FPGA_BASE + 0xa) +#define OMAP1510_FPGA_RST (OMAP1510_FPGA_BASE + 0xb) -#define OMAP1510P1_FPGA_AUDIO (OMAP1510P1_FPGA_BASE + 0xc) -#define OMAP1510P1_FPGA_DIP (OMAP1510P1_FPGA_BASE + 0xe) -#define OMAP1510P1_FPGA_FPGA_IO (OMAP1510P1_FPGA_BASE + 0xf) -#define OMAP1510P1_FPGA_UART1 (OMAP1510P1_FPGA_BASE + 0x14) -#define OMAP1510P1_FPGA_UART2 (OMAP1510P1_FPGA_BASE + 0x15) -#define OMAP1510P1_FPGA_OMAP1510_STATUS (OMAP1510P1_FPGA_BASE + 0x16) -#define OMAP1510P1_FPGA_BOARD_REV (OMAP1510P1_FPGA_BASE + 0x18) -#define OMAP1510P1_PPT_DATA (OMAP1510P1_FPGA_BASE + 0x100) -#define OMAP1510P1_PPT_STATUS (OMAP1510P1_FPGA_BASE + 0x101) -#define OMAP1510P1_PPT_CONTROL (OMAP1510P1_FPGA_BASE + 0x102) - -#define OMAP1510P1_FPGA_TOUCHSCREEN (OMAP1510P1_FPGA_BASE + 0x204) - -#define INNOVATOR_FPGA_INFO (OMAP1510P1_FPGA_BASE + 0x205) -#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510P1_FPGA_BASE + 0x206) -#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510P1_FPGA_BASE + 0x207) -#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510P1_FPGA_BASE + 0x208) -#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510P1_FPGA_BASE + 0x209) -#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510P1_FPGA_BASE + 0x20a) -#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510P1_FPGA_BASE + 0x20b) -#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510P1_FPGA_BASE + 0x20c) -#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510P1_FPGA_BASE + 0x20d) -#define INNOVATOR_FPGA_ISR2 (OMAP1510P1_FPGA_BASE + 0x20e) -#define INNOVATOR_FPGA_IMR2 (OMAP1510P1_FPGA_BASE + 0x210) +#define OMAP1510_FPGA_AUDIO (OMAP1510_FPGA_BASE + 0xc) +#define OMAP1510_FPGA_DIP (OMAP1510_FPGA_BASE + 0xe) +#define OMAP1510_FPGA_FPGA_IO (OMAP1510_FPGA_BASE + 0xf) +#define OMAP1510_FPGA_UART1 (OMAP1510_FPGA_BASE + 0x14) +#define OMAP1510_FPGA_UART2 (OMAP1510_FPGA_BASE + 0x15) +#define OMAP1510_FPGA_OMAP1510_STATUS (OMAP1510_FPGA_BASE + 0x16) +#define OMAP1510_FPGA_BOARD_REV (OMAP1510_FPGA_BASE + 0x18) +#define OMAP1510P1_PPT_DATA (OMAP1510_FPGA_BASE + 0x100) +#define OMAP1510P1_PPT_STATUS (OMAP1510_FPGA_BASE + 0x101) +#define OMAP1510P1_PPT_CONTROL (OMAP1510_FPGA_BASE + 0x102) + +#define OMAP1510_FPGA_TOUCHSCREEN (OMAP1510_FPGA_BASE + 0x204) + +#define INNOVATOR_FPGA_INFO (OMAP1510_FPGA_BASE + 0x205) +#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510_FPGA_BASE + 0x206) +#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510_FPGA_BASE + 0x207) +#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510_FPGA_BASE + 0x208) +#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510_FPGA_BASE + 0x209) +#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510_FPGA_BASE + 0x20a) +#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510_FPGA_BASE + 0x20b) +#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510_FPGA_BASE + 0x20c) +#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510_FPGA_BASE + 0x20d) +#define INNOVATOR_FPGA_ISR2 (OMAP1510_FPGA_BASE + 0x20e) +#define INNOVATOR_FPGA_IMR2 (OMAP1510_FPGA_BASE + 0x210) -#define OMAP1510P1_FPGA_ETHR_START (OMAP1510P1_FPGA_START + 0x300) -#define OMAP1510P1_FPGA_ETHR_BASE (OMAP1510P1_FPGA_BASE + 0x300) +#define OMAP1510_FPGA_ETHR_START (OMAP1510_FPGA_START + 0x300) +#define OMAP1510_FPGA_ETHR_BASE (OMAP1510_FPGA_BASE + 0x300) /* * Power up Giga UART driver, turn on HID clock. * Turn off BT power, since we're not using it and it * draws power. */ -#define OMAP1510P1_FPGA_RESET_VALUE 0x42 +#define OMAP1510_FPGA_RESET_VALUE 0x42 -#define OMAP1510P1_FPGA_PCR_IF_PD0 (1 << 7) -#define OMAP1510P1_FPGA_PCR_COM2_EN (1 << 6) -#define OMAP1510P1_FPGA_PCR_COM1_EN (1 << 5) -#define OMAP1510P1_FPGA_PCR_EXP_PD0 (1 << 4) -#define OMAP1510P1_FPGA_PCR_EXP_PD1 (1 << 3) -#define OMAP1510P1_FPGA_PCR_48MHZ_CLK (1 << 2) -#define OMAP1510P1_FPGA_PCR_4MHZ_CLK (1 << 1) -#define OMAP1510P1_FPGA_PCR_RSRVD_BIT0 (1 << 0) +#define OMAP1510_FPGA_PCR_IF_PD0 (1 << 7) +#define OMAP1510_FPGA_PCR_COM2_EN (1 << 6) +#define OMAP1510_FPGA_PCR_COM1_EN (1 << 5) +#define OMAP1510_FPGA_PCR_EXP_PD0 (1 << 4) +#define OMAP1510_FPGA_PCR_EXP_PD1 (1 << 3) +#define OMAP1510_FPGA_PCR_48MHZ_CLK (1 << 2) +#define OMAP1510_FPGA_PCR_4MHZ_CLK (1 << 1) +#define OMAP1510_FPGA_PCR_RSRVD_BIT0 (1 << 0) /* * Innovator/OMAP1510 FPGA HID register bit definitions diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/bus.h linux-2.6.7/include/asm-arm/arch-omap/bus.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/bus.h 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/bus.h 2004-06-15 23:10:43.716704443 -0700 @@ -72,8 +72,12 @@ * Device ID numbers for bus types */ #define OMAP_OCP_DEVID_USB 0 + +#define OMAP_TIPB_DEVID_OHCI 0 #define OMAP_TIPB_DEVID_LCD 1 #define OMAP_TIPB_DEVID_MMC 2 +#define OMAP_TIPB_DEVID_OTG 3 +#define OMAP_TIPB_DEVID_UDC 4 /* * Virtual bus definitions for OMAP diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/dma.h linux-2.6.7/include/asm-arm/arch-omap/dma.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/dma.h 2004-06-15 23:10:02.393964789 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/dma.h 2004-06-15 23:10:43.756706128 -0700 @@ -33,10 +33,10 @@ #define OMAP_DMA_EXT_NDMA_REQ 5 #define OMAP_DMA_EXT_NDMA_REQ2 6 #define OMAP_DMA_UWIRE_TX 7 -#define OMAP_DMA_MCBSP1_DMA_TX 8 -#define OMAP_DMA_MCBSP1_DMA_RX 9 -#define OMAP_DMA_MCBSP3_DMA_TX 10 -#define OMAP_DMA_MCBSP3_DMA_RX 11 +#define OMAP_DMA_MCBSP1_TX 8 +#define OMAP_DMA_MCBSP1_RX 9 +#define OMAP_DMA_MCBSP3_TX 10 +#define OMAP_DMA_MCBSP3_RX 11 #define OMAP_DMA_UART1_TX 12 #define OMAP_DMA_UART1_RX 13 #define OMAP_DMA_UART2_TX 14 @@ -86,75 +86,77 @@ #define OMAP_DMA_CRYPTO_DES_OUT 56 -#define OMAP_DMA_BASE 0xfffed800 -#define OMAP_DMA_GCR_REG (OMAP_DMA_BASE + 0x400) -#define OMAP_DMA_GSCR_REG (OMAP_DMA_BASE + 0x404) -#define OMAP_DMA_GRST_REG (OMAP_DMA_BASE + 0x408) -#define OMAP_DMA_HW_ID_REG (OMAP_DMA_BASE + 0x442) -#define OMAP_DMA_PCH2_ID_REG (OMAP_DMA_BASE + 0x444) +#define OMAP_DMA_BASE (0xfffed800) +#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400) +#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404) +#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408) +#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442) +#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444) #define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446) #define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448) #define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a) #define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c) -#define OMAP_DMA_CAPS_0_U_REG (OMAP_DMA_BASE + 0x44e) -#define OMAP_DMA_CAPS_0_L_REG (OMAP_DMA_BASE + 0x450) -#define OMAP_DMA_CAPS_1_U_REG (OMAP_DMA_BASE + 0x452) -#define OMAP_DMA_CAPS_1_L_REG (OMAP_DMA_BASE + 0x454) -#define OMAP_DMA_CAPS_2_REG (OMAP_DMA_BASE + 0x456) -#define OMAP_DMA_CAPS_3_REG (OMAP_DMA_BASE + 0x458) -#define OMAP_DMA_CAPS_4_REG (OMAP_DMA_BASE + 0x45a) -#define OMAP_DMA_PCH2_SR_REG (OMAP_DMA_BASE + 0x460) -#define OMAP_DMA_PCH0_SR_REG (OMAP_DMA_BASE + 0x480) -#define OMAP_DMA_PCH1_SR_REG (OMAP_DMA_BASE + 0x482) -#define OMAP_DMA_PCHD_SR_REG (OMAP_DMA_BASE + 0x4c0) - -#define OMAP1510_DMA_LCD_CTRL 0xfffedb00 -#define OMAP1510_DMA_LCD_TOP_F1_L 0xfffedb02 -#define OMAP1510_DMA_LCD_TOP_F1_U 0xfffedb04 -#define OMAP1510_DMA_LCD_BOT_F1_L 0xfffedb06 -#define OMAP1510_DMA_LCD_BOT_F1_U 0xfffedb08 - -#define OMAP1610_DMA_LCD_CSDP 0xfffee3c0 -#define OMAP1610_DMA_LCD_CCR 0xfffee3c2 -#define OMAP1610_DMA_LCD_CTRL 0xfffee3c4 -#define OMAP1610_DMA_LCD_TOP_B1_L 0xfffee3c8 -#define OMAP1610_DMA_LCD_TOP_B1_U 0xfffee3ca -#define OMAP1610_DMA_LCD_BOT_B1_L 0xfffee3cc -#define OMAP1610_DMA_LCD_BOT_B1_U 0xfffee3ce -#define OMAP1610_DMA_LCD_TOP_B2_L 0xfffee3d0 -#define OMAP1610_DMA_LCD_TOP_B2_U 0xfffee3d2 -#define OMAP1610_DMA_LCD_BOT_B2_L 0xfffee3d4 -#define OMAP1610_DMA_LCD_BOT_B2_U 0xfffee3d6 -#define OMAP1610_DMA_LCD_SRC_EI_B1 0xfffee3d8 -#define OMAP1610_DMA_LCD_SRC_FI_B1_L 0xfffee3da -#define OMAP1610_DMA_LCD_SRC_EN_B1 0xfffee3e0 -#define OMAP1610_DMA_LCD_SRC_FN_B1 0xfffee3e4 -#define OMAP1610_DMA_LCD_LCH_CTRL 0xfffee3ea -#define OMAP1610_DMA_LCD_SRC_FI_B1_U 0xfffee3f4 +#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e) +#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450) +#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452) +#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454) +#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456) +#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458) +#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a) +#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460) +#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480) +#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482) +#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0) + +#define OMAP1510_DMA_LCD_BASE (0xfffedb00) +#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00) +#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02) +#define OMAP1510_DMA_LCD_TOP_F1_U (OMAP1510_DMA_LCD_BASE + 0x04) +#define OMAP1510_DMA_LCD_BOT_F1_L (OMAP1510_DMA_LCD_BASE + 0x06) +#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08) + +#define OMAP1610_DMA_LCD_BASE (0xfffee300) +#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0) +#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2) +#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4) +#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8) +#define OMAP1610_DMA_LCD_TOP_B1_U (OMAP1610_DMA_LCD_BASE + 0xca) +#define OMAP1610_DMA_LCD_BOT_B1_L (OMAP1610_DMA_LCD_BASE + 0xcc) +#define OMAP1610_DMA_LCD_BOT_B1_U (OMAP1610_DMA_LCD_BASE + 0xce) +#define OMAP1610_DMA_LCD_TOP_B2_L (OMAP1610_DMA_LCD_BASE + 0xd0) +#define OMAP1610_DMA_LCD_TOP_B2_U (OMAP1610_DMA_LCD_BASE + 0xd2) +#define OMAP1610_DMA_LCD_BOT_B2_L (OMAP1610_DMA_LCD_BASE + 0xd4) +#define OMAP1610_DMA_LCD_BOT_B2_U (OMAP1610_DMA_LCD_BASE + 0xd6) +#define OMAP1610_DMA_LCD_SRC_EI_B1 (OMAP1610_DMA_LCD_BASE + 0xd8) +#define OMAP1610_DMA_LCD_SRC_FI_B1_L (OMAP1610_DMA_LCD_BASE + 0xda) +#define OMAP1610_DMA_LCD_SRC_EN_B1 (OMAP1610_DMA_LCD_BASE + 0xe0) +#define OMAP1610_DMA_LCD_SRC_FN_B1 (OMAP1610_DMA_LCD_BASE + 0xe4) +#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea) +#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4) /* Every LCh has its own set of the registers below */ -#define OMAP_DMA_CSDP_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00) -#define OMAP_DMA_CCR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02) -#define OMAP_DMA_CICR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04) -#define OMAP_DMA_CSR_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06) -#define OMAP_DMA_CSSA_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08) -#define OMAP_DMA_CSSA_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a) -#define OMAP_DMA_CDSA_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c) -#define OMAP_DMA_CDSA_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e) -#define OMAP_DMA_CEN_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10) -#define OMAP_DMA_CFN_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12) -#define OMAP_DMA_CSFI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14) -#define OMAP_DMA_CSEI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16) -#define OMAP_DMA_CSAC_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18) -#define OMAP_DMA_CDAC_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a) -#define OMAP_DMA_CDEI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c) -#define OMAP_DMA_CDFI_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e) -#define OMAP_DMA_COLOR_L_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20) -#define OMAP_DMA_COLOR_U_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22) -#define OMAP_DMA_CCR2_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24) -#define OMAP_DMA_CLNK_CTRL_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28) -#define OMAP_DMA_LCH_CTRL_REG(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a) +#define OMAP_DMA_CSDP(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x00) +#define OMAP_DMA_CCR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x02) +#define OMAP_DMA_CICR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x04) +#define OMAP_DMA_CSR(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x06) +#define OMAP_DMA_CSSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x08) +#define OMAP_DMA_CSSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0a) +#define OMAP_DMA_CDSA_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0c) +#define OMAP_DMA_CDSA_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x0e) +#define OMAP_DMA_CEN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x10) +#define OMAP_DMA_CFN(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x12) +#define OMAP_DMA_CSFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x14) +#define OMAP_DMA_CSEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x16) +#define OMAP_DMA_CSAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x18) +#define OMAP_DMA_CDAC(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1a) +#define OMAP_DMA_CDEI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1c) +#define OMAP_DMA_CDFI(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x1e) +#define OMAP_DMA_COLOR_L(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x20) +#define OMAP_DMA_COLOR_U(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x22) +#define OMAP_DMA_CCR2(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x24) +#define OMAP_DMA_CLNK_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x28) +#define OMAP_DMA_LCH_CTRL(n) (OMAP_DMA_BASE + 0x40 * (n) + 0x2a) #define OMAP_DMA_TOUT_IRQ (1 << 0) #define OMAP_DMA_DROP_IRQ (1 << 1) @@ -192,6 +194,11 @@ OMAP_LCD_DMA_B2_BOTTOM }; +enum { + OMAP_DMA_DATA_BURST_4, + OMAP_DMA_DATA_BURST_8 +}; + extern int omap_request_dma(int dev_id, const char *dev_name, void (* callback)(int lch, u16 ch_status, void *data), void *data, int *dma_ch); @@ -203,10 +210,20 @@ extern void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, int frame_count, int sync_mode); +extern void omap_set_dma_constant_fill(int lch, u32 color); +extern void omap_set_dma_transparent_copy(int lch, u32 color); + extern void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start); +extern void omap_set_dma_src_index(int lch, int eidx, int fidx); +extern void omap_set_dma_src_data_pack(int lch, int enable); +extern void omap_set_dma_src_burst_mode(int lch, int burst_mode); + extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode, unsigned long dest_start); +extern void omap_set_dma_dest_index(int lch, int eidx, int fidx); +extern void omap_set_dma_dest_data_pack(int lch, int enable); +extern void omap_set_dma_dest_burst_mode(int lch, int burst_mode); extern void omap_dma_link_lch (int lch_head, int lch_queue); extern void omap_dma_unlink_lch (int lch_head, int lch_queue); diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/gpio.h linux-2.6.7/include/asm-arm/arch-omap/gpio.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/gpio.h 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/gpio.h 2004-06-15 23:10:43.756706128 -0700 @@ -32,18 +32,18 @@ #define OMAP_MPUIO_BASE 0xfffb5000 #define OMAP_MPUIO_INPUT_LATCH 0x00 -#define OMAP_MPUIO_OUTPUT_REG 0x04 +#define OMAP_MPUIO_OUTPUT 0x04 #define OMAP_MPUIO_IO_CNTL 0x08 #define OMAP_MPUIO_KBR_LATCH 0x10 -#define OMAP_MPUIO_KBC_REG 0x14 -#define OMAP_MPUIO_GPIO_EVENT_MODE_REG 0x18 -#define OMAP_MPUIO_GPIO_INT_EDGE_REG 0x1c +#define OMAP_MPUIO_KBC 0x14 +#define OMAP_MPUIO_GPIO_EVENT_MODE 0x18 +#define OMAP_MPUIO_GPIO_INT_EDGE 0x1c #define OMAP_MPUIO_KBD_INT 0x20 #define OMAP_MPUIO_GPIO_INT 0x24 #define OMAP_MPUIO_KBD_MASKIT 0x28 #define OMAP_MPUIO_GPIO_MASKIT 0x2c -#define OMAP_MPUIO_GPIO_DEBOUNCING_REG 0x30 -#define OMAP_MPUIO_LATCH_REG 0x34 +#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30 +#define OMAP_MPUIO_LATCH 0x34 #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/hardware.h linux-2.6.7/include/asm-arm/arch-omap/hardware.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/hardware.h 2004-06-15 23:10:02.394964832 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/hardware.h 2004-06-15 23:10:43.783707265 -0700 @@ -10,6 +10,7 @@ * Author: RidgeRun, Inc. Greg Lonnon * * Reorganized for Linux-2.6 by Tony Lindgren + * and Dirk Behme * * 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 @@ -40,49 +41,7 @@ #ifndef __ASSEMBLER__ #include #endif - -/* - * ---------------------------------------------------------------------------- - * I/O mapping - * ---------------------------------------------------------------------------- - */ -#define IO_PHYS 0xFFFB0000 -#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ -#define IO_VIRT (IO_PHYS - IO_OFFSET) -#define IO_SIZE 0x40000 -#define IO_ADDRESS(x) ((x) - IO_OFFSET) - -#define PCIO_BASE 0 - -#define io_p2v(x) ((x) - IO_OFFSET) -#define io_v2p(x) ((x) + IO_OFFSET) - -#ifndef __ASSEMBLER__ - -/* 16 bit uses LDRH/STRH, base +/- offset_8 */ -typedef struct { volatile u16 offset[256]; } __regbase16; -#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \ - ->offset[((vaddr)&0xff)>>1] -#define __REG16(paddr) __REGV16(io_p2v(paddr)) - -/* 8/32 bit uses LDR/STR, base +/- offset_12 */ -typedef struct { volatile u8 offset[4096]; } __regbase8; -#define __REGV8(vaddr) ((__regbase8 *)((paddr)&~4095)) \ - ->offset[((paddr)&4095)>>0] -#define __REG8(paddr) __REGV8(io_p2v(paddr)) - -typedef struct { volatile u32 offset[4096]; } __regbase32; -#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \ - ->offset[((vaddr)&4095)>>2] -#define __REG32(paddr) __REGV32(io_p2v(paddr)) - -#else - -#define __REG8(paddr) io_p2v(paddr) -#define __REG16(paddr) io_p2v(paddr) -#define __REG32(paddr) io_p2v(paddr) - -#endif +#include /* * --------------------------------------------------------------------------- @@ -97,14 +56,14 @@ * Clocks * ---------------------------------------------------------------------------- */ -#define CLKGEN_RESET_BASE (0xfffece00) -#define ARM_CKCTL (CLKGEN_RESET_BASE + 0x0) -#define ARM_IDLECT1 (CLKGEN_RESET_BASE + 0x4) -#define ARM_IDLECT2 (CLKGEN_RESET_BASE + 0x8) -#define ARM_EWUPCT (CLKGEN_RESET_BASE + 0xC) -#define ARM_RSTCT1 (CLKGEN_RESET_BASE + 0x10) -#define ARM_RSTCT2 (CLKGEN_RESET_BASE + 0x14) -#define ARM_SYSST (CLKGEN_RESET_BASE + 0x18) +#define CLKGEN_REG_BASE (0xfffece00) +#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0) +#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4) +#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8) +#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC) +#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10) +#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14) +#define ARM_SYSST (CLKGEN_REG_BASE + 0x18) #define CK_RATEF 1 #define CK_IDLEF 2 @@ -113,19 +72,27 @@ #define SETARM_IDLE_SHIFT /* DPLL control registers */ -#define DPLL_CTL_REG (0xfffecf00) -#define CK_DPLL1 (0xfffecf00) +#define DPLL_CTL (0xfffecf00) + +/* DSP clock control */ +#define DSP_CONFIG_REG_BASE (0xe1008000) +#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4) +#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8) -/* ULPD */ +/* + * --------------------------------------------------------------------------- + * UPLD + * --------------------------------------------------------------------------- + */ #define ULPD_REG_BASE (0xfffe0800) -#define ULPD_IT_STATUS_REG (ULPD_REG_BASE + 0x14) -#define ULPD_CLOCK_CTRL_REG (ULPD_REG_BASE + 0x30) -#define ULPD_SOFT_REQ_REG (ULPD_REG_BASE + 0x34) -#define ULPD_DPLL_CTRL_REG (ULPD_REG_BASE + 0x3c) -#define ULPD_STATUS_REQ_REG (ULPD_REG_BASE + 0x40) -#define ULPD_APLL_CTRL_REG (ULPD_REG_BASE + 0x4c) -#define ULPD_POWER_CTRL_REG (ULPD_REG_BASE + 0x50) -#define ULPD_CAM_CLK_CTRL_REG (ULPD_REG_BASE + 0x7c) +#define ULPD_IT_STATUS (ULPD_REG_BASE + 0x14) +#define ULPD_CLOCK_CTRL (ULPD_REG_BASE + 0x30) +#define ULPD_SOFT_REQ (ULPD_REG_BASE + 0x34) +#define ULPD_DPLL_CTRL (ULPD_REG_BASE + 0x3c) +#define ULPD_STATUS_REQ (ULPD_REG_BASE + 0x40) +#define ULPD_APLL_CTRL (ULPD_REG_BASE + 0x4c) +#define ULPD_POWER_CTRL (ULPD_REG_BASE + 0x50) +#define ULPD_CAM_CLK_CTRL (ULPD_REG_BASE + 0x7c) /* * --------------------------------------------------------------------------- @@ -146,18 +113,24 @@ #define TIMER32k_ARL (1<<3) /* MPU Timer base addresses */ -#define OMAP_MPUTIMER_BASE 0xfffec500 -#define OMAP_MPUTIMER_OFF 0x00000100 - -#define OMAP_TIMER1_BASE 0xfffec500 -#define OMAP_TIMER2_BASE 0xfffec600 -#define OMAP_TIMER3_BASE 0xfffec700 -#define OMAP_WATCHDOG_BASE 0xfffec800 +#define OMAP_TIMER1_BASE (0xfffec500) +#define OMAP_TIMER2_BASE (0xfffec600) +#define OMAP_TIMER3_BASE (0xfffec700) +#define OMAP_MPUTIMER_BASE OMAP_TIMER1_BASE +#define OMAP_MPUTIMER_OFFSET 0x100 /* MPU Timer Registers */ -#define CNTL_TIMER 0 -#define LOAD_TIM 4 -#define READ_TIM 8 +#define OMAP_TIMER1_CNTL (OMAP_TIMER_BASE1 + 0x0) +#define OMAP_TIMER1_LOAD_TIM (OMAP_TIMER_BASE1 + 0x4) +#define OMAP_TIMER1_READ_TIM (OMAP_TIMER_BASE1 + 0x8) + +#define OMAP_TIMER2_CNTL (OMAP_TIMER_BASE2 + 0x0) +#define OMAP_TIMER2_LOAD_TIM (OMAP_TIMER_BASE2 + 0x4) +#define OMAP_TIMER2_READ_TIM (OMAP_TIMER_BASE2 + 0x8) + +#define OMAP_TIMER3_CNTL (OMAP_TIMER_BASE3 + 0x0) +#define OMAP_TIMER3_LOAD_TIM (OMAP_TIMER_BASE3 + 0x4) +#define OMAP_TIMER3_READ_TIM (OMAP_TIMER_BASE3 + 0x8) /* CNTL_TIMER register bits */ #define MPUTIM_FREE (1<<6) @@ -167,6 +140,13 @@ #define MPUTIM_AR (1<<1) #define MPUTIM_ST (1<<0) +/* Watchdog */ +#define OMAP_WATCHDOG_BASE (0xfffec800) +#define OMAP_WDT_TIMER (OMAP_WATCHDOG_BASE + 0x0) +#define OMAP_WDT_LOAD_TIM (OMAP_WATCHDOG_BASE + 0x4) +#define OMAP_WDT_READ_TIM (OMAP_WATCHDOG_BASE + 0x4) +#define OMAP_WDT_TIMER_MODE (OMAP_WATCHDOG_BASE + 0x8) + /* * --------------------------------------------------------------------------- * Interrupts @@ -174,22 +154,30 @@ */ #define OMAP_IH1_BASE 0xfffecb00 #define OMAP_IH2_BASE 0xfffe0000 -#define OMAP_ITR 0x0 -#define OMAP_MASK 0x4 -#define IRQ_ITR 0x00 -#define IRQ_MIR 0x04 -#define IRQ_SIR_IRQ 0x10 -#define IRQ_SIR_FIQ 0x14 -#define IRQ_CONTROL_REG 0x18 -#define IRQ_ISR 0x9c -#define IRQ_ILR0 0x1c - -/* OMAP-1610 specific interrupt handler registers */ -#define OMAP_IH2_SECT1 (OMAP_IH2_BASE) -#define OMAP_IH2_SECT2 (OMAP_IH2_BASE + 0x100) -#define OMAP_IH2_SECT3 (OMAP_IH2_BASE + 0x200) -#define OMAP_IH2_SECT4 (OMAP_IH2_BASE + 0x300) +#define OMAP_IH1_ITR (OMAP_IH1_BASE + 0x00) +#define OMAP_IH1_MIR (OMAP_IH1_BASE + 0x04) +#define OMAP_IH1_SIR_IRQ (OMAP_IH1_BASE + 0x10) +#define OMAP_IH1_SIR_FIQ (OMAP_IH1_BASE + 0x14) +#define OMAP_IH1_CONTROL (OMAP_IH1_BASE + 0x18) +#define OMAP_IH1_ILR0 (OMAP_IH1_BASE + 0x1c) +#define OMAP_IH1_ISR (OMAP_IH1_BASE + 0x9c) + +#define OMAP_IH2_ITR (OMAP_IH2_BASE + 0x00) +#define OMAP_IH2_MIR (OMAP_IH2_BASE + 0x04) +#define OMAP_IH2_SIR_IRQ (OMAP_IH2_BASE + 0x10) +#define OMAP_IH2_SIR_FIQ (OMAP_IH2_BASE + 0x14) +#define OMAP_IH2_CONTROL (OMAP_IH2_BASE + 0x18) +#define OMAP_IH2_ILR0 (OMAP_IH2_BASE + 0x1c) +#define OMAP_IH2_ISR (OMAP_IH2_BASE + 0x9c) + +#define IRQ_ITR_REG_OFFSET 0x00 +#define IRQ_MIR_REG_OFFSET 0x04 +#define IRQ_SIR_IRQ_REG_OFFSET 0x10 +#define IRQ_SIR_FIQ_REG_OFFSET 0x14 +#define IRQ_CONTROL_REG_OFFSET 0x18 +#define IRQ_ISR_REG_OFFSET 0x9c +#define IRQ_ILR0_REG_OFFSET 0x1c /* * --------------------------------------------------------------------------- @@ -198,9 +186,9 @@ */ #define TCMIF_BASE 0xfffecc00 #define IMIF_PRIO (TCMIF_BASE + 0x00) -#define EMIFS_PRIO_REG (TCMIF_BASE + 0x04) -#define EMIFF_PRIO_REG (TCMIF_BASE + 0x08) -#define EMIFS_CONFIG_REG (TCMIF_BASE + 0x0c) +#define EMIFS_PRIO (TCMIF_BASE + 0x04) +#define EMIFF_PRIO (TCMIF_BASE + 0x08) +#define EMIFS_CONFIG (TCMIF_BASE + 0x0c) #define EMIFS_CS0_CONFIG (TCMIF_BASE + 0x10) #define EMIFS_CS1_CONFIG (TCMIF_BASE + 0x14) #define EMIFS_CS2_CONFIG (TCMIF_BASE + 0x18) @@ -213,7 +201,6 @@ #define TC_ENDIANISM (TCMIF_BASE + 0x34) #define EMIFF_SDRAM_CONFIG_2 (TCMIF_BASE + 0x3c) #define EMIF_CFG_DYNAMIC_WS (TCMIF_BASE + 0x40) - /* * ---------------------------------------------------------------------------- * System control registers @@ -265,25 +252,24 @@ * --------------------------------------------------------------------------- */ #define TIPB_PUBLIC_CNTL_BASE 0xfffed300 -#define MPU_PUBLIC_TIPB_CNTL_REG (TIPB_PUBLIC_CNTL_BASE + 0x8) +#define MPU_PUBLIC_TIPB_CNTL (TIPB_PUBLIC_CNTL_BASE + 0x8) #define TIPB_PRIVATE_CNTL_BASE 0xfffeca00 -#define MPU_PRIVATE_TIPB_CNTL_REG (TIPB_PRIVATE_CNTL_BASE + 0x8) +#define MPU_PRIVATE_TIPB_CNTL (TIPB_PRIVATE_CNTL_BASE + 0x8) /* * ---------------------------------------------------------------------------- - * DSP control registers + * MPUI interface * ---------------------------------------------------------------------------- */ -/* MPUI Interface Registers */ -#define MPUI_CTRL_REG (0xfffec900) -#define MPUI_DEBUG_ADDR (0xfffec904) -#define MPUI_DEBUG_DATA (0xfffec908) -#define MPUI_DEBUG_FLAG (0xfffec90c) -#define MPUI_STATUS_REG (0xfffec910) -#define MPUI_DSP_STATUS_REG (0xfffec914) -#define MPUI_DSP_BOOT_CONFIG (0xfffec918) -#define MPUI_DSP_API_CONFIG (0xfffec91c) - +#define MPUI_BASE (0xfffec900) +#define MPUI_CTRL (MPUI_BASE + 0x0) +#define MPUI_DEBUG_ADDR (MPUI_BASE + 0x4) +#define MPUI_DEBUG_DATA (MPUI_BASE + 0x8) +#define MPUI_DEBUG_FLAG (MPUI_BASE + 0xc) +#define MPUI_STATUS_REG (MPUI_BASE + 0x10) +#define MPUI_DSP_STATUS (MPUI_BASE + 0x14) +#define MPUI_DSP_BOOT_CONFIG (MPUI_BASE + 0x18) +#define MPUI_DSP_API_CONFIG (MPUI_BASE + 0x1c) #ifndef __ASSEMBLER__ @@ -292,34 +278,38 @@ * Processor differentiation * --------------------------------------------------------------------------- */ -#define OMAP_ID_REG __REG32(0xfffed404) +#define OMAP_ID_BASE (0xfffed400) +#define OMAP_ID_REG __REG32(OMAP_ID_BASE + 0x04) + +#define ID_SHIFT 12 +#define ID_MASK 0x7fff /* See also uncompress.h */ -#define OMAP_ID_730 0xB55F -#define OMAP_ID_1510 0xB470 -#define OMAP_ID_1610 0xB576 -#define OMAP_ID_1710 0xB5F7 -#define OMAP_ID_5912 0xB58C +#define OMAP_ID_730 0x355F +#define OMAP_ID_1510 0x3470 +#define OMAP_ID_1610 0x3576 +#define OMAP_ID_1710 0x35F7 +#define OMAP_ID_5912 0x358C #ifdef CONFIG_ARCH_OMAP730 #include "omap730.h" -#define cpu_is_omap730() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_730) +#define cpu_is_omap730() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_730) #else #define cpu_is_omap730() 0 #endif #ifdef CONFIG_ARCH_OMAP1510 #include "omap1510.h" -#define cpu_is_omap1510() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1510) +#define cpu_is_omap1510() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1510) #else #define cpu_is_omap1510() 0 #endif #ifdef CONFIG_ARCH_OMAP1610 #include "omap1610.h" -#define cpu_is_omap1710() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1710) +#define cpu_is_omap1710() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1710) /* Detect 1710 as 1610 for now */ -#define cpu_is_omap1610() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_1610 \ +#define cpu_is_omap1610() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_1610 \ || cpu_is_omap1710()) #else #define cpu_is_omap1610() 0 @@ -328,7 +318,7 @@ #ifdef CONFIG_ARCH_OMAP5912 #include "omap5912.h" -#define cpu_is_omap5912() (((OMAP_ID_REG >> 12) & 0xffff) == OMAP_ID_5912) +#define cpu_is_omap5912() (((OMAP_ID_REG >> ID_SHIFT) & ID_MASK) == OMAP_ID_5912) #else #define cpu_is_omap5912() 0 #endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/io.h linux-2.6.7/include/asm-arm/arch-omap/io.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/io.h 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/io.h 2004-06-15 23:10:43.784707307 -0700 @@ -1,13 +1,36 @@ /* * linux/include/asm-arm/arch-omap/io.h * + * IO definitions for TI OMAP processors and boards + * * Copied from linux/include/asm-arm/arch-sa1100/io.h * Copyright (C) 1997-1999 Russell King * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * * Modifications: * 06-12-1997 RMK Created. * 07-04-1999 RMK Major cleanup */ + #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H @@ -22,6 +45,24 @@ #define __mem_isa(a) ((unsigned long)(a)) /* + * ---------------------------------------------------------------------------- + * I/O mapping + * ---------------------------------------------------------------------------- + */ +#define IO_PHYS 0xFFFB0000 +#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */ +#define IO_VIRT (IO_PHYS - IO_OFFSET) +#define IO_SIZE 0x40000 +#define IO_ADDRESS(x) ((x) - IO_OFFSET) + +#define PCIO_BASE 0 + +#define io_p2v(x) ((x) - IO_OFFSET) +#define io_v2p(x) ((x) + IO_OFFSET) + +#ifndef __ASSEMBLER__ + +/* * Functions to access the OMAP IO region * * NOTE: - Use omap_read/write[bwl] for physical register addresses @@ -38,4 +79,29 @@ #define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v)) #define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v)) +/* 16 bit uses LDRH/STRH, base +/- offset_8 */ +typedef struct { volatile u16 offset[256]; } __regbase16; +#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \ + ->offset[((vaddr)&0xff)>>1] +#define __REG16(paddr) __REGV16(io_p2v(paddr)) + +/* 8/32 bit uses LDR/STR, base +/- offset_12 */ +typedef struct { volatile u8 offset[4096]; } __regbase8; +#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \ + ->offset[((vaddr)&4095)>>0] +#define __REG8(paddr) __REGV8(io_p2v(paddr)) + +typedef struct { volatile u32 offset[4096]; } __regbase32; +#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \ + ->offset[((vaddr)&4095)>>2] +#define __REG32(paddr) __REGV32(io_p2v(paddr)) + +#else + +#define __REG8(paddr) io_p2v(paddr) +#define __REG16(paddr) io_p2v(paddr) +#define __REG32(paddr) io_p2v(paddr) + +#endif + #endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/mux.h linux-2.6.7/include/asm-arm/arch-omap/mux.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/mux.h 2004-06-15 23:10:02.395964874 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/mux.h 2004-06-15 23:10:43.831709286 -0700 @@ -140,16 +140,20 @@ R18_1510_USB_GPIO0, W4_USB_PUEN, W4_USB_CLKO, + W4_USB_HIGHZ, + W4_GPIO58, /* USB1 master */ USB1_SUSP, USB1_SEO, + W13_1610_USB1_SE0, USB1_TXEN, USB1_TXD, USB1_VP, USB1_VM, USB1_RCV, USB1_SPEED, + R13_1610_USB1_SPEED, /* USB2 master */ USB2_SUSP, @@ -216,6 +220,7 @@ /* OMAP-1610 GPIO */ P20_1610_GPIO4, V9_1610_GPIO7, + W8_1610_GPIO9, N19_1610_GPIO13, P10_1610_GPIO22, V5_1610_GPIO24, @@ -317,16 +322,20 @@ MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1) MUX_CFG("W4_USB_PUEN", D, 3, 0, 3, 5, 1, NA, 0, 1) MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1) +MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1) +MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1) /* USB1 master */ MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1) MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1) +MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1) MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1) MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1) MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1) MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1) MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1) MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1) +MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1) /* USB2 master */ MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1) @@ -394,6 +403,7 @@ /* OMAP-1610 GPIO */ MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1) MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1) +MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1) MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1) MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1) MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1) @@ -405,7 +415,7 @@ MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1) MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1) MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) -MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, NA, 0, 0, NA, 0, 0) +MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) /* First MMC interface, same on 1510 and 1610 */ MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1) diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-h2.h linux-2.6.7/include/asm-arm/arch-omap/omap-h2.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-h2.h 2004-05-09 19:33:13.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap-h2.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,35 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/omap-h2.h - * - * Hardware definitions for TI OMAP1610 H2 board. - * - * Cleanup for Linux-2.6 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_OMAP_H2_H -#define __ASM_ARCH_OMAP_H2_H - -/* Placeholder for H2 specific defines */ - -#endif /* __ASM_ARCH_OMAP_H2_H */ - diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-innovator.h linux-2.6.7/include/asm-arm/arch-omap/omap-innovator.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-innovator.h 2004-05-09 19:32:37.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap-innovator.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,214 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/omap-innovator.h - * - * Copyright (C) 2001 RidgeRun, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __ASM_ARCH_OMAP_INNOVATOR_H -#define __ASM_ARCH_OMAP_INNOVATOR_H - -#if defined (CONFIG_ARCH_OMAP1510) - -/* - * --------------------------------------------------------------------------- - * OMAP-1510 FPGA - * --------------------------------------------------------------------------- - */ -#define OMAP1510P1_FPGA_BASE 0xE8000000 /* Virtual */ -#define OMAP1510P1_FPGA_SIZE SZ_4K -#define OMAP1510P1_FPGA_START 0x08000000 /* Physical */ - -/* Revision */ -#define OMAP1510P1_FPGA_REV_LOW (OMAP1510P1_FPGA_BASE + 0x0) -#define OMAP1510P1_FPGA_REV_HIGH (OMAP1510P1_FPGA_BASE + 0x1) - -#define OMAP1510P1_FPGA_LCD_PANEL_CONTROL (OMAP1510P1_FPGA_BASE + 0x2) -#define OMAP1510P1_FPGA_LED_DIGIT (OMAP1510P1_FPGA_BASE + 0x3) -#define INNOVATOR_FPGA_HID_SPI (OMAP1510P1_FPGA_BASE + 0x4) -#define OMAP1510P1_FPGA_POWER (OMAP1510P1_FPGA_BASE + 0x5) - -/* Interrupt status */ -#define OMAP1510P1_FPGA_ISR_LO (OMAP1510P1_FPGA_BASE + 0x6) -#define OMAP1510P1_FPGA_ISR_HI (OMAP1510P1_FPGA_BASE + 0x7) - -/* Interrupt mask */ -#define OMAP1510P1_FPGA_IMR_LO (OMAP1510P1_FPGA_BASE + 0x8) -#define OMAP1510P1_FPGA_IMR_HI (OMAP1510P1_FPGA_BASE + 0x9) - -/* Reset registers */ -#define OMAP1510P1_FPGA_HOST_RESET (OMAP1510P1_FPGA_BASE + 0xa) -#define OMAP1510P1_FPGA_RST (OMAP1510P1_FPGA_BASE + 0xb) - -#define OMAP1510P1_FPGA_AUDIO (OMAP1510P1_FPGA_BASE + 0xc) -#define OMAP1510P1_FPGA_DIP (OMAP1510P1_FPGA_BASE + 0xe) -#define OMAP1510P1_FPGA_FPGA_IO (OMAP1510P1_FPGA_BASE + 0xf) -#define OMAP1510P1_FPGA_UART1 (OMAP1510P1_FPGA_BASE + 0x14) -#define OMAP1510P1_FPGA_UART2 (OMAP1510P1_FPGA_BASE + 0x15) -#define OMAP1510P1_FPGA_OMAP1510_STATUS (OMAP1510P1_FPGA_BASE + 0x16) -#define OMAP1510P1_FPGA_BOARD_REV (OMAP1510P1_FPGA_BASE + 0x18) -#define OMAP1510P1_PPT_DATA (OMAP1510P1_FPGA_BASE + 0x100) -#define OMAP1510P1_PPT_STATUS (OMAP1510P1_FPGA_BASE + 0x101) -#define OMAP1510P1_PPT_CONTROL (OMAP1510P1_FPGA_BASE + 0x102) - -#define OMAP1510P1_FPGA_TOUCHSCREEN (OMAP1510P1_FPGA_BASE + 0x204) - -#define INNOVATOR_FPGA_INFO (OMAP1510P1_FPGA_BASE + 0x205) -#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510P1_FPGA_BASE + 0x206) -#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510P1_FPGA_BASE + 0x207) -#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510P1_FPGA_BASE + 0x208) -#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510P1_FPGA_BASE + 0x209) -#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510P1_FPGA_BASE + 0x20a) -#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510P1_FPGA_BASE + 0x20b) -#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510P1_FPGA_BASE + 0x20c) -#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510P1_FPGA_BASE + 0x20d) -#define INNOVATOR_FPGA_ISR2 (OMAP1510P1_FPGA_BASE + 0x20e) -#define INNOVATOR_FPGA_IMR2 (OMAP1510P1_FPGA_BASE + 0x210) - -#define OMAP1510P1_FPGA_ETHR_START (OMAP1510P1_FPGA_START + 0x300) -#define OMAP1510P1_FPGA_ETHR_BASE (OMAP1510P1_FPGA_BASE + 0x300) - -/* - * Power up Giga UART driver, turn on HID clock. - * Turn off BT power, since we're not using it and it - * draws power. - */ -#define OMAP1510P1_FPGA_RESET_VALUE 0x42 - -#define OMAP1510P1_FPGA_PCR_IF_PD0 (1 << 7) -#define OMAP1510P1_FPGA_PCR_COM2_EN (1 << 6) -#define OMAP1510P1_FPGA_PCR_COM1_EN (1 << 5) -#define OMAP1510P1_FPGA_PCR_EXP_PD0 (1 << 4) -#define OMAP1510P1_FPGA_PCR_EXP_PD1 (1 << 3) -#define OMAP1510P1_FPGA_PCR_48MHZ_CLK (1 << 2) -#define OMAP1510P1_FPGA_PCR_4MHZ_CLK (1 << 1) -#define OMAP1510P1_FPGA_PCR_RSRVD_BIT0 (1 << 0) - -/* - * Innovator/OMAP1510 FPGA HID register bit definitions - */ -#define FPGA_HID_SCLK (1<<0) /* output */ -#define FPGA_HID_MOSI (1<<1) /* output */ -#define FPGA_HID_nSS (1<<2) /* output 0/1 chip idle/select */ -#define FPGA_HID_nHSUS (1<<3) /* output 0/1 host active/suspended */ -#define FPGA_HID_MISO (1<<4) /* input */ -#define FPGA_HID_ATN (1<<5) /* input 0/1 chip idle/ATN */ -#define FPGA_HID_rsrvd (1<<6) -#define FPGA_HID_RESETn (1<<7) /* output - 0/1 USAR reset/run */ - -#ifndef OMAP_SDRAM_DEVICE -#define OMAP_SDRAM_DEVICE D256M_1X16_4B -#endif - -#define OMAP1510P1_IMIF_PRI_VALUE 0x00 -#define OMAP1510P1_EMIFS_PRI_VALUE 0x00 -#define OMAP1510P1_EMIFF_PRI_VALUE 0x00 - -/* - * These definitions define an area of FLASH set aside - * for the use of MTD/JFFS2. This is the area of flash - * that a JFFS2 filesystem will reside which is mounted - * at boot with the "root=/dev/mtdblock/0 rw" - * command line option. The flash address used here must - * fall within the legal range defined by rrload for storing - * the filesystem component. This address will be sufficiently - * deep into the overall flash range to avoid the other - * components also stored in flash such as the bootloader, - * the bootloader params, and the kernel. - * The SW2 settings for the map below are: - * 1 off, 2 off, 3 on, 4 off. - */ - -/* Intel flash_0, partitioned as expected by rrload */ -#define OMAP_FLASH_0_BASE 0xD8000000 -#define OMAP_FLASH_0_START 0x00000000 -#define OMAP_FLASH_0_SIZE SZ_16M - -/* Intel flash_1, used for cramfs or other flash file systems */ -#define OMAP_FLASH_1_BASE 0xD9000000 -#define OMAP_FLASH_1_START 0x01000000 -#define OMAP_FLASH_1_SIZE SZ_16M - -/* The FPGA IRQ is cascaded through GPIO_13 */ -#define INT_FPGA (IH_GPIO_BASE + 13) - -/* IRQ Numbers for interrupts muxed through the FPGA */ -#define IH_FPGA_BASE IH_BOARD_BASE -#define INT_FPGA_ATN (IH_FPGA_BASE + 0) -#define INT_FPGA_ACK (IH_FPGA_BASE + 1) -#define INT_FPGA2 (IH_FPGA_BASE + 2) -#define INT_FPGA3 (IH_FPGA_BASE + 3) -#define INT_FPGA4 (IH_FPGA_BASE + 4) -#define INT_FPGA5 (IH_FPGA_BASE + 5) -#define INT_FPGA6 (IH_FPGA_BASE + 6) -#define INT_FPGA7 (IH_FPGA_BASE + 7) -#define INT_FPGA8 (IH_FPGA_BASE + 8) -#define INT_FPGA9 (IH_FPGA_BASE + 9) -#define INT_FPGA10 (IH_FPGA_BASE + 10) -#define INT_FPGA11 (IH_FPGA_BASE + 11) -#define INT_FPGA12 (IH_FPGA_BASE + 12) -#define INT_ETHER (IH_FPGA_BASE + 13) -#define INT_FPGAUART1 (IH_FPGA_BASE + 14) -#define INT_FPGAUART2 (IH_FPGA_BASE + 15) -#define INT_FPGA_TS (IH_FPGA_BASE + 16) -#define INT_FPGA17 (IH_FPGA_BASE + 17) -#define INT_FPGA_CAM (IH_FPGA_BASE + 18) -#define INT_FPGA_RTC_A (IH_FPGA_BASE + 19) -#define INT_FPGA_RTC_B (IH_FPGA_BASE + 20) -#define INT_FPGA_CD (IH_FPGA_BASE + 21) -#define INT_FPGA22 (IH_FPGA_BASE + 22) -#define INT_FPGA23 (IH_FPGA_BASE + 23) - -#define NR_FPGA_IRQS 24 - -#define MAXIRQNUM (IH_FPGA_BASE + NR_FPGA_IRQS - 1) -#define MAXFIQNUM MAXIRQNUM -#define MAXSWINUM MAXIRQNUM - -#define NR_IRQS 256 - -#ifndef __ASSEMBLY__ -void fpga_write(unsigned char val, int reg); -unsigned char fpga_read(int reg); -#endif - -#elif defined (CONFIG_ARCH_OMAP1610) - -/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */ -#define OMAP1610_ETHR_BASE 0xE8000000 -#define OMAP1610_ETHR_SIZE SZ_4K -#define OMAP1610_ETHR_START 0x04000000 - -/* Intel STRATA NOR flash at CS3 */ -#define OMAP1610_NOR_FLASH_BASE 0xD8000000 -#define OMAP1610_NOR_FLASH_SIZE SZ_32M -#define OMAP1610_NOR_FLASH_START 0x0C000000 - -#define MAXIRQNUM (IH_BOARD_BASE) -#define MAXFIQNUM MAXIRQNUM -#define MAXSWINUM MAXIRQNUM - -#define NR_IRQS (MAXIRQNUM + 1) - -#else -#error "Only OMAP1510 and OMAP1610 Innovator supported!" -#endif -#endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-perseus2.h linux-2.6.7/include/asm-arm/arch-omap/omap-perseus2.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap-perseus2.h 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap-perseus2.h 1969-12-31 16:00:00.000000000 -0800 @@ -1,152 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/omap-perseus2.h - * - * Copyright 2003 by Texas Instruments Incorporated - * OMAP730 / P2-sample additions - * Author: Jean Pihet - * - * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com) - * Author: RidgeRun, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __ASM_ARCH_OMAP_P2SAMPLE_H -#define __ASM_ARCH_OMAP_P2SAMPLE_H - -#if defined(CONFIG_ARCH_OMAP730) && defined (CONFIG_MACH_OMAP_PERSEUS2) - -/* - * NOTE: ALL DEFINITIONS IN THIS FILE NEED TO BE PREFIXED BY IDENTIFIER - * P2SAMPLE_ since they are specific to the EVM and not the chip. - */ - -/* --------------------------------------------------------------------------- - * OMAP730 Debug Board FPGA - * --------------------------------------------------------------------------- - * - */ - -/* maps in the FPGA registers and the ETHR registers */ -#define OMAP730_FPGA_BASE 0xE8000000 /* VA */ -#define OMAP730_FPGA_SIZE SZ_4K /* SIZE */ -#define OMAP730_FPGA_START 0x04000000 /* PA */ - -#define OMAP730_FPGA_ETHR_START OMAP730_FPGA_START -#define OMAP730_FPGA_ETHR_BASE OMAP730_FPGA_BASE -#define OMAP730_FPGA_FPGA_REV (OMAP730_FPGA_BASE + 0x10) /* FPGA Revision */ -#define OMAP730_FPGA_BOARD_REV (OMAP730_FPGA_BASE + 0x12) /* Board Revision */ -#define OMAP730_FPGA_GPIO (OMAP730_FPGA_BASE + 0x14) /* GPIO outputs */ -#define OMAP730_FPGA_LEDS (OMAP730_FPGA_BASE + 0x16) /* LEDs outputs */ -#define OMAP730_FPGA_MISC_INPUTS (OMAP730_FPGA_BASE + 0x18) /* Misc inputs */ -#define OMAP730_FPGA_LAN_STATUS (OMAP730_FPGA_BASE + 0x1A) /* LAN Status line */ -#define OMAP730_FPGA_LAN_RESET (OMAP730_FPGA_BASE + 0x1C) /* LAN Reset line */ - -// LEDs definition on debug board (16 LEDs) -#define OMAP730_FPGA_LED_CLAIMRELEASE (1 << 15) -#define OMAP730_FPGA_LED_STARTSTOP (1 << 14) -#define OMAP730_FPGA_LED_HALTED (1 << 13) -#define OMAP730_FPGA_LED_IDLE (1 << 12) -#define OMAP730_FPGA_LED_TIMER (1 << 11) -// cpu0 load-meter LEDs -#define OMAP730_FPGA_LOAD_METER (1 << 0) // A bit of fun on our board ... -#define OMAP730_FPGA_LOAD_METER_SIZE 11 -#define OMAP730_FPGA_LOAD_METER_MASK ((1 << OMAP730_FPGA_LOAD_METER_SIZE) - 1) - -#ifndef OMAP_SDRAM_DEVICE -#define OMAP_SDRAM_DEVICE D256M_1X16_4B -#endif - - -/* - * These definitions define an area of FLASH set aside - * for the use of MTD/JFFS2. This is the area of flash - * that a JFFS2 filesystem will reside which is mounted - * at boot with the "root=/dev/mtdblock/0 rw" - * command line option. - */ - -/* Intel flash_0, partitioned as expected by rrload */ -#define OMAP_FLASH_0_BASE 0xD8000000 /* VA */ -#define OMAP_FLASH_0_START 0x00000000 /* PA */ -#define OMAP_FLASH_0_SIZE SZ_32M - -/* 2.9.6 Traffic Controller Memory Interface Registers */ -#define OMAP_FLASH_CFG_0 0xfffecc10 -#define OMAP_FLASH_ACFG_0 0xfffecc50 - -#define OMAP_FLASH_CFG_1 0xfffecc14 -#define OMAP_FLASH_ACFG_1 0xfffecc54 - -/* - * Configuration Registers - */ -#define PERSEUS2_CONFIG_BASE 0xfffe1000 -#define PERSEUS2_IO_CONF_0 0xfffe1070 -#define PERSEUS2_IO_CONF_1 0xfffe1074 -#define PERSEUS2_IO_CONF_2 0xfffe1078 -#define PERSEUS2_IO_CONF_3 0xfffe107c -#define PERSEUS2_IO_CONF_4 0xfffe1080 -#define PERSEUS2_IO_CONF_5 0xfffe1084 -#define PERSEUS2_IO_CONF_6 0xfffe1088 -#define PERSEUS2_IO_CONF_7 0xfffe108c -#define PERSEUS2_IO_CONF_8 0xfffe1090 -#define PERSEUS2_IO_CONF_9 0xfffe1094 -#define PERSEUS2_IO_CONF_10 0xfffe1098 -#define PERSEUS2_IO_CONF_11 0xfffe109c -#define PERSEUS2_IO_CONF_12 0xfffe10a0 -#define PERSEUS2_IO_CONF_13 0xfffe10a4 - -#define PERSEUS2_MODE_1 0xfffe1010 -#define PERSEUS2_MODE_2 0xfffe1014 - -/* CSMI specials: in terms of base + offset */ -#define PERSEUS2_MODE2_OFFSET 0x14 - -/* DSP control: ICR registers */ -#define ICR_BASE 0xfffbb800 -/* M_CTL */ -#define DSP_M_CTL ((volatile __u16 *)0xfffbb804) -/* DSP control: MMU registers */ -#define DSP_MMU_BASE ((volatile __u16 *)0xfffed200) - -/* The Ethernet Controller IRQ is cascaded to MPU_EXT_nIRQ througb the FPGA */ -#define INT_ETHER INT_730_MPU_EXT_NIRQ - -#define MAXIRQNUM IH_BOARD_BASE -#define MAXFIQNUM MAXIRQNUM -#define MAXSWINUM MAXIRQNUM - -#define NR_IRQS (MAXIRQNUM + 1) - -#ifndef __ASSEMBLY__ -void fpga_write(unsigned char val, int reg); -unsigned char fpga_read(int reg); -#endif - -/* PCC_UPLD control register: OMAP730 */ -#define PCC_UPLD_CTRL_REG_BASE (0xfffe0900) -#define PCC_UPLD_CTRL_REG (volatile __u16 *)(PCC_UPLD_CTRL_REG_BASE + 0x00) - -#else -#error "Only OMAP730 Perseus2 supported!" -#endif - -#endif diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap1610.h linux-2.6.7/include/asm-arm/arch-omap/omap1610.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap1610.h 2004-05-09 19:31:58.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap1610.h 2004-06-15 23:10:43.846709918 -0700 @@ -48,20 +48,60 @@ #define OMAP1610_DSPREG_SIZE SZ_128K #define OMAP1610_DSPREG_START 0xE1000000 -#define OMAP_IH2_0_BASE 0xfffe0000 -#define OMAP_IH2_1_BASE 0xfffe0100 -#define OMAP_IH2_2_BASE 0xfffe0200 -#define OMAP_IH2_3_BASE 0xfffe0300 +/* + * --------------------------------------------------------------------------- + * Interrupts + * --------------------------------------------------------------------------- + */ +#define OMAP_IH2_0_BASE (0xfffe0000) +#define OMAP_IH2_1_BASE (0xfffe0100) +#define OMAP_IH2_2_BASE (0xfffe0200) +#define OMAP_IH2_3_BASE (0xfffe0300) + +#define OMAP_IH2_0_ITR (OMAP_IH2_0_BASE + 0x00) +#define OMAP_IH2_0_MIR (OMAP_IH2_0_BASE + 0x04) +#define OMAP_IH2_0_SIR_IRQ (OMAP_IH2_0_BASE + 0x10) +#define OMAP_IH2_0_SIR_FIQ (OMAP_IH2_0_BASE + 0x14) +#define OMAP_IH2_0_CONTROL (OMAP_IH2_0_BASE + 0x18) +#define OMAP_IH2_0_ILR0 (OMAP_IH2_0_BASE + 0x1c) +#define OMAP_IH2_0_ISR (OMAP_IH2_0_BASE + 0x9c) + +#define OMAP_IH2_1_ITR (OMAP_IH2_1_BASE + 0x00) +#define OMAP_IH2_1_MIR (OMAP_IH2_1_BASE + 0x04) +#define OMAP_IH2_1_SIR_IRQ (OMAP_IH2_1_BASE + 0x10) +#define OMAP_IH2_1_SIR_FIQ (OMAP_IH2_1_BASE + 0x14) +#define OMAP_IH2_1_CONTROL (OMAP_IH2_1_BASE + 0x18) +#define OMAP_IH2_1_ILR1 (OMAP_IH2_1_BASE + 0x1c) +#define OMAP_IH2_1_ISR (OMAP_IH2_1_BASE + 0x9c) + +#define OMAP_IH2_2_ITR (OMAP_IH2_2_BASE + 0x00) +#define OMAP_IH2_2_MIR (OMAP_IH2_2_BASE + 0x04) +#define OMAP_IH2_2_SIR_IRQ (OMAP_IH2_2_BASE + 0x10) +#define OMAP_IH2_2_SIR_FIQ (OMAP_IH2_2_BASE + 0x14) +#define OMAP_IH2_2_CONTROL (OMAP_IH2_2_BASE + 0x18) +#define OMAP_IH2_2_ILR2 (OMAP_IH2_2_BASE + 0x1c) +#define OMAP_IH2_2_ISR (OMAP_IH2_2_BASE + 0x9c) + +#define OMAP_IH2_3_ITR (OMAP_IH2_3_BASE + 0x00) +#define OMAP_IH2_3_MIR (OMAP_IH2_3_BASE + 0x04) +#define OMAP_IH2_3_SIR_IRQ (OMAP_IH2_3_BASE + 0x10) +#define OMAP_IH2_3_SIR_FIQ (OMAP_IH2_3_BASE + 0x14) +#define OMAP_IH2_3_CONTROL (OMAP_IH2_3_BASE + 0x18) +#define OMAP_IH2_3_ILR3 (OMAP_IH2_3_BASE + 0x1c) +#define OMAP_IH2_3_ISR (OMAP_IH2_3_BASE + 0x9c) /* * ---------------------------------------------------------------------------- - * System control registers + * Clocks * ---------------------------------------------------------------------------- */ +#define OMAP1610_ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24) -#define OMAP1610_RESET_CONTROL 0xfffe1140 -#define OMAP1610_ARM_IDLECT3 (CLKGEN_RESET_BASE + 0x24) -#define OMAP1610_CONF_VOLTAGE_CTRL_0 0xfffe1060 +/* + * ---------------------------------------------------------------------------- + * Pin configuration registers + * ---------------------------------------------------------------------------- + */ #define OMAP1610_CONF_VOLTAGE_VDDSHV6 (1 << 8) #define OMAP1610_CONF_VOLTAGE_VDDSHV7 (1 << 9) #define OMAP1610_CONF_VOLTAGE_VDDSHV8 (1 << 10) @@ -73,14 +113,8 @@ * TIPB bus interface * --------------------------------------------------------------------------- */ - -#define OMAP1610_TIPB_SWITCH 0xfffbc800 -#define OMAP1610_TIPB_BRIDGE_INT 0xfffeca00 /* Private TIPB_CNTL */ -#define OMAP1610_PRIVATE_MPU_TIPB_CNTL 0xfffeca08 -#define OMAP1610_TIPB_BRIDGE_EXT 0xfffed300 /* Public (Shared) TIPB_CNTL */ -#define OMAP1610_PUBLIC_MPU_TIPB_CNTL 0xfffed308 -#define OMAP1610_TIPB_SWITCH_CFG OMAP_TIPB_SWITCH -#define OMAP1610_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_CFG + 0x160) +#define TIPB_SWITCH_BASE (0xfffbc800) +#define OMAP1610_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_BASE + 0x160) #endif /* __ASM_ARCH_OMAP1610_H */ diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap5912.h linux-2.6.7/include/asm-arm/arch-omap/omap5912.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap5912.h 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap5912.h 2004-06-15 23:10:43.846709918 -0700 @@ -50,12 +50,54 @@ #define OMAP5912_DSPREG_START 0xE1000000 /* + * --------------------------------------------------------------------------- + * Interrupts + * --------------------------------------------------------------------------- + */ +#define OMAP_IH2_0_BASE (0xfffe0000) +#define OMAP_IH2_1_BASE (0xfffe0100) +#define OMAP_IH2_2_BASE (0xfffe0200) +#define OMAP_IH2_3_BASE (0xfffe0300) + +#define OMAP_IH2_0_ITR (OMAP_IH2_0_BASE + 0x00) +#define OMAP_IH2_0_MIR (OMAP_IH2_0_BASE + 0x04) +#define OMAP_IH2_0_SIR_IRQ (OMAP_IH2_0_BASE + 0x10) +#define OMAP_IH2_0_SIR_FIQ (OMAP_IH2_0_BASE + 0x14) +#define OMAP_IH2_0_CONTROL (OMAP_IH2_0_BASE + 0x18) +#define OMAP_IH2_0_ILR0 (OMAP_IH2_0_BASE + 0x1c) +#define OMAP_IH2_0_ISR (OMAP_IH2_0_BASE + 0x9c) + +#define OMAP_IH2_1_ITR (OMAP_IH2_1_BASE + 0x00) +#define OMAP_IH2_1_MIR (OMAP_IH2_1_BASE + 0x04) +#define OMAP_IH2_1_SIR_IRQ (OMAP_IH2_1_BASE + 0x10) +#define OMAP_IH2_1_SIR_FIQ (OMAP_IH2_1_BASE + 0x14) +#define OMAP_IH2_1_CONTROL (OMAP_IH2_1_BASE + 0x18) +#define OMAP_IH2_1_ILR1 (OMAP_IH2_1_BASE + 0x1c) +#define OMAP_IH2_1_ISR (OMAP_IH2_1_BASE + 0x9c) + +#define OMAP_IH2_2_ITR (OMAP_IH2_2_BASE + 0x00) +#define OMAP_IH2_2_MIR (OMAP_IH2_2_BASE + 0x04) +#define OMAP_IH2_2_SIR_IRQ (OMAP_IH2_2_BASE + 0x10) +#define OMAP_IH2_2_SIR_FIQ (OMAP_IH2_2_BASE + 0x14) +#define OMAP_IH2_2_CONTROL (OMAP_IH2_2_BASE + 0x18) +#define OMAP_IH2_2_ILR2 (OMAP_IH2_2_BASE + 0x1c) +#define OMAP_IH2_2_ISR (OMAP_IH2_2_BASE + 0x9c) + +#define OMAP_IH2_3_ITR (OMAP_IH2_3_BASE + 0x00) +#define OMAP_IH2_3_MIR (OMAP_IH2_3_BASE + 0x04) +#define OMAP_IH2_3_SIR_IRQ (OMAP_IH2_3_BASE + 0x10) +#define OMAP_IH2_3_SIR_FIQ (OMAP_IH2_3_BASE + 0x14) +#define OMAP_IH2_3_CONTROL (OMAP_IH2_3_BASE + 0x18) +#define OMAP_IH2_3_ILR3 (OMAP_IH2_3_BASE + 0x1c) +#define OMAP_IH2_3_ISR (OMAP_IH2_3_BASE + 0x9c) + +/* * ---------------------------------------------------------------------------- * System control registers * ---------------------------------------------------------------------------- */ -#define OMAP5912_ARM_IDLECT3 (CLKGEN_RESET_BASE + 0x24) +#define OMAP5912_ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24) #endif /* __ASM_ARCH_OMAP5912_H */ diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/omap730.h linux-2.6.7/include/asm-arm/arch-omap/omap730.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/omap730.h 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/omap730.h 2004-06-15 23:10:43.847709960 -0700 @@ -105,8 +105,8 @@ * OMAP730 PCC_UPLD configuration registers * ---------------------------------------------------------------------------- */ -#define OMAP730_PCC_UPLD_CTRL_REG_BASE (0xfffe0900) -#define OMAP730_PCC_UPLD_CTRL_REG (OMAP730_PCC_UPLD_CTRL_REG_BASE + 0x00) +#define OMAP730_PCC_UPLD_CTRL_BASE (0xfffe0900) +#define OMAP730_PCC_UPLD_CTRL (OMAP730_PCC_UPLD_CTRL_BASE + 0x00) #endif /* __ASM_ARCH_OMAP730_H */ diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/time.h linux-2.6.7/include/asm-arm/arch-omap/time.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/time.h 2004-05-09 19:32:38.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/time.h 2004-06-15 23:10:43.847709960 -0700 @@ -52,7 +52,7 @@ #define mputimer_base(n) \ ((volatile mputimer_regs_t*)IO_ADDRESS(OMAP_MPUTIMER_BASE + \ - (n)*OMAP_MPUTIMER_OFF)) + (n)*OMAP_MPUTIMER_OFFSET)) static inline unsigned long timer32k_read(int reg) { unsigned long val; diff -urN linux-2.6.7-rc3/include/asm-arm/arch-omap/uncompress.h linux-2.6.7/include/asm-arm/arch-omap/uncompress.h --- linux-2.6.7-rc3/include/asm-arm/arch-omap/uncompress.h 2004-06-15 23:10:02.395964874 -0700 +++ linux-2.6.7/include/asm-arm/arch-omap/uncompress.h 2004-06-15 23:10:43.847709960 -0700 @@ -25,7 +25,7 @@ #define UART_OMAP_MDR1 0x08 /* mode definition register */ #define check_port(base, shift) ((base[UART_OMAP_MDR1 << shift] & 7) == 0) -#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & 0xffff +#define omap_get_id() ((*(volatile unsigned int *)(0xfffed404)) >> 12) & ID_MASK static void puts(const char *s) diff -urN linux-2.6.7-rc3/include/asm-arm/arch-s3c2410/regs-gpio.h linux-2.6.7/include/asm-arm/arch-s3c2410/regs-gpio.h --- linux-2.6.7-rc3/include/asm-arm/arch-s3c2410/regs-gpio.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-s3c2410/regs-gpio.h 2004-06-15 23:10:43.968715055 -0700 @@ -574,12 +574,7 @@ #define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C) #define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0) -/* mask: 0=enable, 1=disable - * 1 bit EINT, 4=EINT4, 23=EINT23 - * EINT0,1,2,3 are not handled here. -*/ -#define S3C2410_EINTMASK S3C2410_GPIOREG(0xA4) -#define S3C2410_EINTPEND S3C2410_GPIOREG(0xA8) +/* removed EINTxxxx defs from here, not meant for this */ /* GSTATUS have miscellaneous information in them * diff -urN linux-2.6.7-rc3/include/asm-arm/arch-s3c2410/regs-irq.h linux-2.6.7/include/asm-arm/arch-s3c2410/regs-irq.h --- linux-2.6.7-rc3/include/asm-arm/arch-s3c2410/regs-irq.h 2004-05-09 19:32:36.000000000 -0700 +++ linux-2.6.7/include/asm-arm/arch-s3c2410/regs-irq.h 2004-06-15 23:10:43.968715055 -0700 @@ -32,6 +32,11 @@ #define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018) #define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C) +/* mask: 0=enable, 1=disable + * 1 bit EINT, 4=EINT4, 23=EINT23 + * EINT0,1,2,3 are not handled here. +*/ + #define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) #define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) diff -urN linux-2.6.7-rc3/include/asm-arm/uaccess.h linux-2.6.7/include/asm-arm/uaccess.h --- linux-2.6.7-rc3/include/asm-arm/uaccess.h 2004-05-09 19:32:52.000000000 -0700 +++ linux-2.6.7/include/asm-arm/uaccess.h 2004-06-15 23:10:44.114721203 -0700 @@ -13,7 +13,7 @@ */ #include #include -#include +#include #include #include diff -urN linux-2.6.7-rc3/include/asm-arm/unistd.h linux-2.6.7/include/asm-arm/unistd.h --- linux-2.6.7-rc3/include/asm-arm/unistd.h 2004-06-15 23:10:02.423966052 -0700 +++ linux-2.6.7/include/asm-arm/unistd.h 2004-06-15 23:10:44.115721245 -0700 @@ -466,6 +466,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-arm26/unistd.h linux-2.6.7/include/asm-arm26/unistd.h --- linux-2.6.7-rc3/include/asm-arm26/unistd.h 2004-06-15 23:10:02.427966221 -0700 +++ linux-2.6.7/include/asm-arm26/unistd.h 2004-06-15 23:10:44.217725540 -0700 @@ -397,6 +397,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-cris/unistd.h linux-2.6.7/include/asm-cris/unistd.h --- linux-2.6.7-rc3/include/asm-cris/unistd.h 2004-06-15 23:10:02.435966557 -0700 +++ linux-2.6.7/include/asm-cris/unistd.h 2004-06-15 23:10:44.406733499 -0700 @@ -314,6 +314,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-h8300/unistd.h linux-2.6.7/include/asm-h8300/unistd.h --- linux-2.6.7-rc3/include/asm-h8300/unistd.h 2004-06-15 23:10:02.454967357 -0700 +++ linux-2.6.7/include/asm-h8300/unistd.h 2004-06-15 23:10:44.696745711 -0700 @@ -468,6 +468,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-i386/acpi.h linux-2.6.7/include/asm-i386/acpi.h --- linux-2.6.7-rc3/include/asm-i386/acpi.h 2004-06-15 23:10:02.455967399 -0700 +++ linux-2.6.7/include/asm-i386/acpi.h 2004-06-15 23:10:44.703746005 -0700 @@ -122,6 +122,8 @@ #define FIX_ACPI_PAGES 4 extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); +extern int (*platform_rename_gsi)(int ioapic, int gsi); + #ifdef CONFIG_X86_IO_APIC extern int skip_ioapic_setup; extern int acpi_skip_timer_override; diff -urN linux-2.6.7-rc3/include/asm-i386/i387.h linux-2.6.7/include/asm-i386/i387.h --- linux-2.6.7-rc3/include/asm-i386/i387.h 2004-05-09 19:33:06.000000000 -0700 +++ linux-2.6.7/include/asm-i386/i387.h 2004-06-15 23:10:44.878753375 -0700 @@ -51,7 +51,7 @@ #define __clear_fpu( tsk ) \ do { \ if ((tsk)->thread_info->status & TS_USEDFPU) { \ - asm volatile("fwait"); \ + asm volatile("fnclex ; fwait"); \ (tsk)->thread_info->status &= ~TS_USEDFPU; \ stts(); \ } \ diff -urN linux-2.6.7-rc3/include/asm-i386/unistd.h linux-2.6.7/include/asm-i386/unistd.h --- linux-2.6.7-rc3/include/asm-i386/unistd.h 2004-06-15 23:10:02.464967778 -0700 +++ linux-2.6.7/include/asm-i386/unistd.h 2004-06-15 23:10:45.062761123 -0700 @@ -403,6 +403,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-ia64/unistd.h linux-2.6.7/include/asm-ia64/unistd.h --- linux-2.6.7-rc3/include/asm-ia64/unistd.h 2004-06-15 23:10:02.474968199 -0700 +++ linux-2.6.7/include/asm-ia64/unistd.h 2004-06-15 23:10:45.508779904 -0700 @@ -275,6 +275,7 @@ # define __ARCH_WANT_SYS_OLDUMOUNT # define __ARCH_WANT_SYS_SIGPENDING # define __ARCH_WANT_SYS_SIGPROCMASK +# define __ARCH_WANT_SYS_RT_SIGACTION #endif #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER) diff -urN linux-2.6.7-rc3/include/asm-m68k/unistd.h linux-2.6.7/include/asm-m68k/unistd.h --- linux-2.6.7-rc3/include/asm-m68k/unistd.h 2004-06-15 23:10:02.497969167 -0700 +++ linux-2.6.7/include/asm-m68k/unistd.h 2004-06-15 23:10:45.914797001 -0700 @@ -359,6 +359,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-m68knommu/unistd.h linux-2.6.7/include/asm-m68knommu/unistd.h --- linux-2.6.7-rc3/include/asm-m68knommu/unistd.h 2004-06-15 23:10:02.501969335 -0700 +++ linux-2.6.7/include/asm-m68knommu/unistd.h 2004-06-15 23:10:46.005800833 -0700 @@ -394,6 +394,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-mips/unistd.h linux-2.6.7/include/asm-mips/unistd.h --- linux-2.6.7-rc3/include/asm-mips/unistd.h 2004-06-15 23:10:02.509969672 -0700 +++ linux-2.6.7/include/asm-mips/unistd.h 2004-06-15 23:10:46.322814182 -0700 @@ -1091,6 +1091,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION # ifndef __mips64 # define __ARCH_WANT_STAT64 # endif diff -urN linux-2.6.7-rc3/include/asm-parisc/unistd.h linux-2.6.7/include/asm-parisc/unistd.h --- linux-2.6.7-rc3/include/asm-parisc/unistd.h 2004-06-15 23:10:02.520970135 -0700 +++ linux-2.6.7/include/asm-parisc/unistd.h 2004-06-15 23:10:46.908838858 -0700 @@ -899,6 +899,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif /* mmap & mmap2 take 6 arguments */ diff -urN linux-2.6.7-rc3/include/asm-ppc/mpc8260.h linux-2.6.7/include/asm-ppc/mpc8260.h --- linux-2.6.7-rc3/include/asm-ppc/mpc8260.h 2004-05-09 19:31:57.000000000 -0700 +++ linux-2.6.7/include/asm-ppc/mpc8260.h 2004-06-15 23:10:47.016843406 -0700 @@ -16,6 +16,10 @@ #include #endif +#ifdef CONFIG_SBC82xx +#include +#endif + #ifdef CONFIG_SBS8260 #include #endif diff -urN linux-2.6.7-rc3/include/asm-ppc/unistd.h linux-2.6.7/include/asm-ppc/unistd.h --- linux-2.6.7-rc3/include/asm-ppc/unistd.h 2004-06-15 23:10:02.535970767 -0700 +++ linux-2.6.7/include/asm-ppc/unistd.h 2004-06-15 23:10:47.131848249 -0700 @@ -402,6 +402,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION /* * Forking from kernel space will result in the child getting a new, diff -urN linux-2.6.7-rc3/include/asm-ppc64/current.h linux-2.6.7/include/asm-ppc64/current.h --- linux-2.6.7-rc3/include/asm-ppc64/current.h 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/include/asm-ppc64/current.h 2004-06-15 23:10:47.218851913 -0700 @@ -8,13 +8,11 @@ * 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. - * - * Use r13 for current since the ppc64 ABI reserves it - Anton */ #include -#define get_current() ((struct task_struct *)(get_paca()->xCurrent)) +#define get_current() (get_paca()->xCurrent) #define current get_current() #endif /* !(_PPC64_CURRENT_H) */ diff -urN linux-2.6.7-rc3/include/asm-ppc64/io.h linux-2.6.7/include/asm-ppc64/io.h --- linux-2.6.7-rc3/include/asm-ppc64/io.h 2004-06-15 23:10:02.538970893 -0700 +++ linux-2.6.7/include/asm-ppc64/io.h 2004-06-15 23:10:47.269854060 -0700 @@ -307,7 +307,7 @@ static inline void out_be32(volatile unsigned *addr, int val) { - __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" + __asm__ __volatile__("stw%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val)); } @@ -356,9 +356,9 @@ : "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr)); } -static inline void out_be64(volatile unsigned long *addr, int val) +static inline void out_be64(volatile unsigned long *addr, unsigned long val) { - __asm__ __volatile__("std %1,0(%0); sync" : "=m" (*addr) : "r" (val)); + __asm__ __volatile__("std%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val)); } #ifndef CONFIG_PPC_ISERIES diff -urN linux-2.6.7-rc3/include/asm-ppc64/paca.h linux-2.6.7/include/asm-ppc64/paca.h --- linux-2.6.7-rc3/include/asm-ppc64/paca.h 2004-06-15 23:10:02.541971019 -0700 +++ linux-2.6.7/include/asm-ppc64/paca.h 2004-06-15 23:10:47.351857513 -0700 @@ -37,6 +37,8 @@ register struct paca_struct *local_paca asm("r13"); #define get_paca() local_paca +struct task_struct; + /*============================================================================ * Name_______: paca * @@ -59,7 +61,7 @@ */ struct ItLpPaca *xLpPacaPtr; /* Pointer to LpPaca for PLIC 0x00 */ struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */ - u64 xCurrent; /* Pointer to current 0x10 */ + struct task_struct *xCurrent; /* Pointer to current 0x10 */ /* Note: the spinlock functions in arch/ppc64/lib/locks.c load lock_token and xPacaIndex with a single lwz instruction, using the constant offset 24. If you move either field, fix the spinlocks and rwlocks. */ diff -urN linux-2.6.7-rc3/include/asm-ppc64/unistd.h linux-2.6.7/include/asm-ppc64/unistd.h --- linux-2.6.7-rc3/include/asm-ppc64/unistd.h 2004-06-15 23:10:02.549971356 -0700 +++ linux-2.6.7/include/asm-ppc64/unistd.h 2004-06-15 23:10:47.457861977 -0700 @@ -439,6 +439,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset); diff -urN linux-2.6.7-rc3/include/asm-ppc64/vio.h linux-2.6.7/include/asm-ppc64/vio.h --- linux-2.6.7-rc3/include/asm-ppc64/vio.h 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/include/asm-ppc64/vio.h 2004-06-15 23:10:47.457861977 -0700 @@ -43,8 +43,6 @@ int vio_register_driver(struct vio_driver *drv); void vio_unregister_driver(struct vio_driver *drv); -const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, - const struct vio_dev *dev); struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev); void __devinit vio_unregister_device(struct vio_dev *dev); @@ -52,7 +50,6 @@ const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length); int vio_get_irq(struct vio_dev *dev); -struct iommu_table * vio_build_iommu_table(struct vio_dev *dev); int vio_enable_interrupts(struct vio_dev *dev); int vio_disable_interrupts(struct vio_dev *dev); @@ -110,8 +107,6 @@ * The vio_dev structure is used to describe virtual I/O devices. */ struct vio_dev { - struct device_node *archdata; /* Open Firmware node */ - void *driver_data; /* data private to the driver */ struct iommu_table *iommu_table; /* vio_map_* uses this */ uint32_t unit_address; unsigned int irq; diff -urN linux-2.6.7-rc3/include/asm-s390/checksum.h linux-2.6.7/include/asm-s390/checksum.h --- linux-2.6.7-rc3/include/asm-s390/checksum.h 2004-05-09 19:31:58.000000000 -0700 +++ linux-2.6.7/include/asm-s390/checksum.h 2004-06-15 23:10:47.551865936 -0700 @@ -93,8 +93,8 @@ * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -static inline unsigned int -csum_partial_copy_from_user (const char *src, char *dst, +static inline unsigned int +csum_partial_copy_from_user(const char __user *src, char *dst, int len, unsigned int sum, int *err_ptr) { diff -urN linux-2.6.7-rc3/include/asm-s390/compat.h linux-2.6.7/include/asm-s390/compat.h --- linux-2.6.7-rc3/include/asm-s390/compat.h 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/include/asm-s390/compat.h 2004-06-15 23:10:47.551865936 -0700 @@ -123,19 +123,19 @@ */ typedef u32 compat_uptr_t; -static inline void *compat_ptr(compat_uptr_t uptr) +static inline void __user *compat_ptr(compat_uptr_t uptr) { - return (void *)(unsigned long)(uptr & 0x7fffffffUL); + return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); } -static inline void *compat_alloc_user_space(long len) +static inline void __user *compat_alloc_user_space(long len) { unsigned long stack; stack = KSTK_ESP(current); if (test_thread_flag(TIF_31BIT)) stack &= 0x7fffffffUL; - return (void *) (stack - len); + return (void __user *) (stack - len); } struct compat_ipc64_perm { diff -urN linux-2.6.7-rc3/include/asm-s390/debug.h linux-2.6.7/include/asm-s390/debug.h --- linux-2.6.7-rc3/include/asm-s390/debug.h 2004-05-09 19:32:37.000000000 -0700 +++ linux-2.6.7/include/asm-s390/debug.h 2004-06-15 23:10:47.552865978 -0700 @@ -91,7 +91,8 @@ char* out_buf); typedef int (debug_input_proc_t) (debug_info_t* id, struct debug_view* view, - struct file* file, const char* user_buf, + struct file* file, + const char __user *user_buf, size_t in_buf_size, loff_t* offset); int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view, @@ -234,26 +235,6 @@ #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) #endif /* DASD_DEBUG */ -#if DASD_DEBUG > 4 -#define INTERNAL_ERROR(x...) PRINT_FATAL ( INTERNAL_ERRMSG ( x ) ) -#elif DASD_DEBUG > 2 -#define INTERNAL_ERROR(x...) PRINT_ERR ( INTERNAL_ERRMSG ( x ) ) -#elif DASD_DEBUG > 0 -#define INTERNAL_ERROR(x...) PRINT_WARN ( INTERNAL_ERRMSG ( x ) ) -#else -#define INTERNAL_ERROR(x...) -#endif /* DASD_DEBUG */ - -#if DASD_DEBUG > 5 -#define INTERNAL_CHECK(x...) PRINT_FATAL ( INTERNAL_CHKMSG ( x ) ) -#elif DASD_DEBUG > 3 -#define INTERNAL_CHECK(x...) PRINT_ERR ( INTERNAL_CHKMSG ( x ) ) -#elif DASD_DEBUG > 1 -#define INTERNAL_CHECK(x...) PRINT_WARN ( INTERNAL_CHKMSG ( x ) ) -#else -#define INTERNAL_CHECK(x...) -#endif /* DASD_DEBUG */ - #undef DEBUG_MALLOC #ifdef DEBUG_MALLOC void *b; diff -urN linux-2.6.7-rc3/include/asm-s390/idals.h linux-2.6.7/include/asm-s390/idals.h --- linux-2.6.7-rc3/include/asm-s390/idals.h 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/include/asm-s390/idals.h 2004-06-15 23:10:47.552865978 -0700 @@ -218,7 +218,7 @@ * Copy count bytes from an idal buffer to user memory */ static inline size_t -idal_buffer_to_user(struct idal_buffer *ib, void *to, size_t count) +idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count) { size_t left; int i; @@ -228,7 +228,7 @@ left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE); if (left) return left + count - IDA_BLOCK_SIZE; - to = (void *) to + IDA_BLOCK_SIZE; + to = (void __user *) to + IDA_BLOCK_SIZE; count -= IDA_BLOCK_SIZE; } return copy_to_user(to, ib->data[i], count); @@ -238,7 +238,7 @@ * Copy count bytes from user memory to an idal buffer */ static inline size_t -idal_buffer_from_user(struct idal_buffer *ib, const void *from, size_t count) +idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count) { size_t left; int i; @@ -248,7 +248,7 @@ left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE); if (left) return left + count - IDA_BLOCK_SIZE; - from = (void *) from + IDA_BLOCK_SIZE; + from = (void __user *) from + IDA_BLOCK_SIZE; count -= IDA_BLOCK_SIZE; } return copy_from_user(ib->data[i], from, count); diff -urN linux-2.6.7-rc3/include/asm-s390/ipc.h linux-2.6.7/include/asm-s390/ipc.h --- linux-2.6.7-rc3/include/asm-s390/ipc.h 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/include/asm-s390/ipc.h 2004-06-15 23:10:47.552865978 -0700 @@ -15,7 +15,7 @@ * See arch/s390/kernel/sys_s390.c for ugly details.. */ struct ipc_kludge { - struct msgbuf *msgp; + struct msgbuf __user *msgp; long msgtyp; }; diff -urN linux-2.6.7-rc3/include/asm-s390/ptrace.h linux-2.6.7/include/asm-s390/ptrace.h --- linux-2.6.7-rc3/include/asm-s390/ptrace.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/asm-s390/ptrace.h 2004-06-15 23:10:47.623868968 -0700 @@ -303,6 +303,7 @@ */ struct pt_regs { + unsigned long args[1]; psw_t psw; unsigned long gprs[NUM_GPRS]; unsigned long orig_gpr2; diff -urN linux-2.6.7-rc3/include/asm-s390/setup.h linux-2.6.7/include/asm-s390/setup.h --- linux-2.6.7-rc3/include/asm-s390/setup.h 2004-05-09 19:33:19.000000000 -0700 +++ linux-2.6.7/include/asm-s390/setup.h 2004-06-15 23:10:47.625869052 -0700 @@ -12,6 +12,7 @@ #define COMMAND_LINE_SIZE 896 #define RAMDISK_ORIGIN 0x800000 #define RAMDISK_SIZE 0x800000 +#define MEMORY_CHUNKS 16 /* max 0x7fff */ #ifndef __ASSEMBLY__ diff -urN linux-2.6.7-rc3/include/asm-s390/spinlock.h linux-2.6.7/include/asm-s390/spinlock.h --- linux-2.6.7-rc3/include/asm-s390/spinlock.h 2004-06-15 23:10:02.554971566 -0700 +++ linux-2.6.7/include/asm-s390/spinlock.h 2004-06-15 23:10:47.626869094 -0700 @@ -48,7 +48,7 @@ { #ifndef __s390x__ unsigned int reg1, reg2; - __asm__ __volatile(" bras %0,1f\n" + __asm__ __volatile__(" bras %0,1f\n" "0: diag 0,0,68\n" "1: slr %1,%1\n" " cs %1,%0,0(%3)\n" @@ -58,7 +58,7 @@ : "cc", "memory" ); #else /* __s390x__ */ unsigned long reg1, reg2; - __asm__ __volatile(" bras %1,1f\n" + __asm__ __volatile__(" bras %1,1f\n" "0: " __DIAG44_INSN " 0,%4\n" "1: slr %0,%0\n" " cs %0,%1,0(%3)\n" @@ -74,7 +74,7 @@ unsigned long reg; unsigned int result; - __asm__ __volatile(" basr %1,0\n" + __asm__ __volatile__(" basr %1,0\n" "0: cs %0,%1,0(%3)" : "=d" (result), "=&d" (reg), "=m" (lp->lock) : "a" (&lp->lock), "m" (lp->lock), "0" (0) @@ -86,7 +86,7 @@ { unsigned int old; - __asm__ __volatile("cs %0,%3,0(%4)" + __asm__ __volatile__("cs %0,%3,0(%4)" : "=d" (old), "=m" (lp->lock) : "0" (lp->lock), "d" (0), "a" (lp) : "cc", "memory" ); diff -urN linux-2.6.7-rc3/include/asm-s390/string.h linux-2.6.7/include/asm-s390/string.h --- linux-2.6.7-rc3/include/asm-s390/string.h 2004-05-09 19:33:22.000000000 -0700 +++ linux-2.6.7/include/asm-s390/string.h 2004-06-15 23:10:47.627869136 -0700 @@ -15,136 +15,124 @@ #include #endif -#define __HAVE_ARCH_MEMCHR -#define __HAVE_ARCH_MEMCPY -#define __HAVE_ARCH_MEMSET -#define __HAVE_ARCH_STRCAT -#define __HAVE_ARCH_STRCMP -#define __HAVE_ARCH_STRCPY -#define __HAVE_ARCH_STRLEN -#define __HAVE_ARCH_STRNCPY +#define __HAVE_ARCH_BCOPY /* arch function */ +#define __HAVE_ARCH_MEMCHR /* inline & arch function */ +#define __HAVE_ARCH_MEMCMP /* arch function */ +#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ +#define __HAVE_ARCH_MEMSCAN /* inline & arch function */ +#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ +#define __HAVE_ARCH_STRCAT /* inline & arch function */ +#define __HAVE_ARCH_STRCMP /* arch function */ +#define __HAVE_ARCH_STRCPY /* inline & arch function */ +#define __HAVE_ARCH_STRLCAT /* arch function */ +#define __HAVE_ARCH_STRLCPY /* arch function */ +#define __HAVE_ARCH_STRLEN /* inline & arch function */ +#define __HAVE_ARCH_STRNCAT /* arch function */ +#define __HAVE_ARCH_STRNCPY /* arch function */ +#define __HAVE_ARCH_STRNLEN /* inline & arch function */ +#define __HAVE_ARCH_STRRCHR /* arch function */ +#define __HAVE_ARCH_STRSTR /* arch function */ + +/* Prototypes for non-inlined arch strings functions. */ +extern int memcmp(const void *, const void *, size_t); +extern void *memcpy(void *, const void *, size_t); +extern void *memset(void *, int, size_t); +extern int strcmp(const char *,const char *); +extern size_t strlcat(char *, const char *, size_t); +extern size_t strlcpy(char *, const char *, size_t); +extern char *strncat(char *, const char *, size_t); +extern char *strncpy(char *, const char *, size_t); +extern char *strrchr(const char *, int); +extern char *strstr(const char *, const char *); #undef __HAVE_ARCH_MEMMOVE -#undef __HAVE_ARCH_STRNICMP -#undef __HAVE_ARCH_STRNCAT -#undef __HAVE_ARCH_STRNCMP #undef __HAVE_ARCH_STRCHR -#undef __HAVE_ARCH_STRRCHR -#undef __HAVE_ARCH_STRNLEN -#undef __HAVE_ARCH_STRSPN +#undef __HAVE_ARCH_STRNCHR +#undef __HAVE_ARCH_STRNCMP +#undef __HAVE_ARCH_STRNICMP #undef __HAVE_ARCH_STRPBRK -#undef __HAVE_ARCH_STRTOK -#undef __HAVE_ARCH_BCOPY -#undef __HAVE_ARCH_MEMCMP -#undef __HAVE_ARCH_MEMSCAN -#undef __HAVE_ARCH_STRSTR +#undef __HAVE_ARCH_STRSEP +#undef __HAVE_ARCH_STRSPN -extern void *memset(void *, int, size_t); -extern void *memcpy(void *, const void *, size_t); -extern void *memmove(void *, const void *, size_t); -extern char *strncpy(char *, const char *, size_t); -extern int strcmp(const char *,const char *); +#if !defined(IN_ARCH_STRING_C) + +static inline void *memchr(const void * s, int c, size_t n) +{ + register int r0 asm("0") = (char) c; + const void *ret = s + n; -static inline void * memchr(const void * cs,int c,size_t count) + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + " jl 1f\n" + " la %0,0\n" + "1:" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + return (void *) ret; +} + +static inline void *memscan(void *s, int c, size_t n) +{ + register int r0 asm("0") = (char) c; + const void *ret = s + n; + + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); + return (void *) ret; +} + +static inline char *strcat(char *dst, const char *src) +{ + register int r0 asm("0") = 0; + unsigned long dummy; + char *ret = dst; + + asm volatile ("0: srst %0,%1\n" + " jo 0b\n" + "1: mvst %0,%2\n" + " jo 1b" + : "=&a" (dummy), "+a" (dst), "+a" (src) + : "d" (r0), "0" (0) : "cc", "memory" ); + return ret; +} + +static inline char *strcpy(char *dst, const char *src) { - void *ptr; + register int r0 asm("0") = 0; + char *ret = dst; - __asm__ __volatile__ ( -#ifndef __s390x__ - " lr 0,%2\n" - " lr 1,%1\n" - " la %0,0(%3,%1)\n" - "0: srst %0,1\n" - " jo 0b\n" - " brc 13,1f\n" - " slr %0,%0\n" -#else /* __s390x__ */ - " lgr 0,%2\n" - " lgr 1,%1\n" - " la %0,0(%3,%1)\n" - "0: srst %0,1\n" - " jo 0b\n" - " brc 13,1f\n" - " slgr %0,%0\n" -#endif /* __s390x__ */ - "1:" - : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count) - : "cc", "0", "1" ); - return ptr; -} - -static __inline__ char *strcpy(char *dest, const char *src) -{ - char *tmp = dest; - - __asm__ __volatile__ ( -#ifndef __s390x__ - " sr 0,0\n" - "0: mvst %0,%1\n" - " jo 0b" -#else /* __s390x__ */ - " slgr 0,0\n" - "0: mvst %0,%1\n" - " jo 0b" -#endif /* __s390x__ */ - : "+&a" (dest), "+&a" (src) : - : "cc", "memory", "0" ); - return tmp; -} - -static __inline__ size_t strlen(const char *s) -{ - size_t len; - - __asm__ __volatile__ ( -#ifndef __s390x__ - " sr 0,0\n" - " lr %0,%1\n" - "0: srst 0,%0\n" - " jo 0b\n" - " lr %0,0\n" - " sr %0,%1" -#else /* __s390x__ */ - " slgr 0,0\n" - " lgr %0,%1\n" - "0: srst 0,%0\n" - " jo 0b\n" - " lgr %0,0\n" - " sgr %0,%1" -#endif /* __s390x__ */ - : "=&a" (len) : "a" (s) - : "cc", "0" ); - return len; -} - -static __inline__ char *strcat(char *dest, const char *src) -{ - char *tmp = dest; - - __asm__ __volatile__ ( -#ifndef __s390x__ - " sr 0,0\n" - "0: srst 0,%0\n" - " jo 0b\n" - " lr %0,0\n" - " sr 0,0\n" - "1: mvst %0,%1\n" - " jo 1b" -#else /* __s390x__ */ - " slgr 0,0\n" - "0: srst 0,%0\n" - " jo 0b\n" - " lgr %0,0\n" - " slgr 0,0\n" - "1: mvst %0,%1\n" - " jo 1b" -#endif /* __s390x__ */ - : "+&a" (dest), "+&a" (src) : - : "cc", "memory", "0" ); - return tmp; + asm volatile ("0: mvst %0,%1\n" + " jo 0b" + : "+&a" (dst), "+&a" (src) : "d" (r0) + : "cc", "memory" ); + return ret; } -extern void *alloca(size_t); +static inline size_t strlen(const char *s) +{ + register unsigned long r0 asm("0") = 0; + const char *tmp = s; + + asm volatile ("0: srst %0,%1\n" + " jo 0b" + : "+d" (r0), "+a" (tmp) : : "cc" ); + return r0 - (unsigned long) s; +} + +static inline size_t strnlen(const char * s, size_t n) +{ + register int r0 asm("0") = 0; + const char *tmp = s; + const char *end = s + n; + + asm volatile ("0: srst %0,%1\n" + " jo 0b" + : "+a" (end), "+a" (tmp) : "d" (r0) : "cc" ); + return end - s; +} + +#endif /* !IN_ARCH_STRING_C */ + #endif /* __KERNEL__ */ #endif /* __S390_STRING_H_ */ diff -urN linux-2.6.7-rc3/include/asm-s390/thread_info.h linux-2.6.7/include/asm-s390/thread_info.h --- linux-2.6.7-rc3/include/asm-s390/thread_info.h 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/include/asm-s390/thread_info.h 2004-06-15 23:10:47.627869136 -0700 @@ -85,6 +85,7 @@ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ +#define TIF_SINGLE_STEP 6 /* single stepped svc */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ @@ -96,6 +97,7 @@ #define _TIF_NEED_RESCHED (1< +#include #ifdef CONFIG_PCI #include diff -urN linux-2.6.7-rc3/include/asm-sparc/highmem.h linux-2.6.7/include/asm-sparc/highmem.h --- linux-2.6.7-rc3/include/asm-sparc/highmem.h 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/include/asm-sparc/highmem.h 2004-06-15 23:10:47.902880716 -0700 @@ -24,7 +24,7 @@ #include #include #include -#include +#include /* declarations for highmem.c */ extern unsigned long highstart_pfn, highend_pfn; @@ -43,7 +43,7 @@ */ #define LAST_PKMAP 1024 #define PKMAP_SIZE (LAST_PKMAP << PAGE_SHIFT) -#define PKMAP_BASE SRMMU_PMD_ALIGN_SOFT(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT)) +#define PKMAP_BASE PMD_ALIGN(SRMMU_NOCACHE_VADDR + (SRMMU_MAX_NOCACHE_PAGES << PAGE_SHIFT)) #define LAST_PKMAP_MASK (LAST_PKMAP - 1) #define PKMAP_NR(virt) ((virt - PKMAP_BASE) >> PAGE_SHIFT) diff -urN linux-2.6.7-rc3/include/asm-sparc/pgtable.h linux-2.6.7/include/asm-sparc/pgtable.h --- linux-2.6.7-rc3/include/asm-sparc/pgtable.h 2004-06-15 23:10:02.562971903 -0700 +++ linux-2.6.7/include/asm-sparc/pgtable.h 2004-06-15 23:10:47.942882401 -0700 @@ -75,29 +75,10 @@ #define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len) #define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba) -/* - */ -BTFIXUPDEF_SIMM13(pmd_shift) -BTFIXUPDEF_SETHI(pmd_size) -BTFIXUPDEF_SETHI(pmd_mask) - -extern unsigned int pmd_align(unsigned int addr) __attribute_const__; -extern __inline__ unsigned int pmd_align(unsigned int addr) -{ - return ((addr + ~BTFIXUP_SETHI(pmd_mask)) & BTFIXUP_SETHI(pmd_mask)); -} - BTFIXUPDEF_SIMM13(pgdir_shift) BTFIXUPDEF_SETHI(pgdir_size) BTFIXUPDEF_SETHI(pgdir_mask) -extern unsigned int pgdir_align(unsigned int addr) __attribute_const__; -extern __inline__ unsigned int pgdir_align(unsigned int addr) -{ - return ((addr + ~BTFIXUP_SETHI(pgdir_mask)) & BTFIXUP_SETHI(pgdir_mask)); -} - -BTFIXUPDEF_SIMM13(ptrs_per_pte) BTFIXUPDEF_SIMM13(ptrs_per_pmd) BTFIXUPDEF_SIMM13(ptrs_per_pgd) BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) @@ -112,19 +93,19 @@ BTFIXUPDEF_INT(page_readonly) BTFIXUPDEF_INT(page_kernel) -#define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift) -#define PMD_SIZE BTFIXUP_SETHI(pmd_size) -#define PMD_MASK BTFIXUP_SETHI(pmd_mask) -#define PMD_ALIGN(addr) pmd_align(addr) +#define PMD_SHIFT SUN4C_PMD_SHIFT +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PMD_ALIGN(__addr) (((__addr) + ~PMD_MASK) & PMD_MASK) #define PGDIR_SHIFT BTFIXUP_SIMM13(pgdir_shift) #define PGDIR_SIZE BTFIXUP_SETHI(pgdir_size) #define PGDIR_MASK BTFIXUP_SETHI(pgdir_mask) -#define PGDIR_ALIGN pgdir_align(addr) -#define PTRS_PER_PTE BTFIXUP_SIMM13(ptrs_per_pte) +#define PTRS_PER_PTE 1024 #define PTRS_PER_PMD BTFIXUP_SIMM13(ptrs_per_pmd) #define PTRS_PER_PGD BTFIXUP_SIMM13(ptrs_per_pgd) #define USER_PTRS_PER_PGD BTFIXUP_SIMM13(user_ptrs_per_pgd) #define FIRST_USER_PGD_NR 0 +#define PTE_SIZE (PTRS_PER_PTE*4) #define PAGE_NONE __pgprot(BTFIXUP_INT(page_none)) #define PAGE_SHARED __pgprot(BTFIXUP_INT(page_shared)) diff -urN linux-2.6.7-rc3/include/asm-sparc/pgtsrmmu.h linux-2.6.7/include/asm-sparc/pgtsrmmu.h --- linux-2.6.7-rc3/include/asm-sparc/pgtsrmmu.h 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/include/asm-sparc/pgtsrmmu.h 2004-06-15 23:10:47.947882611 -0700 @@ -17,10 +17,10 @@ #define SRMMU_MAX_CONTEXTS 65536 /* PMD_SHIFT determines the size of the area a second-level page table entry can map */ -#define SRMMU_PMD_SHIFT 18 -#define SRMMU_PMD_SIZE (1UL << SRMMU_PMD_SHIFT) -#define SRMMU_PMD_MASK (~(SRMMU_PMD_SIZE-1)) -/* #define SRMMU_PMD_ALIGN(addr) (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK) */ +#define SRMMU_REAL_PMD_SHIFT 18 +#define SRMMU_REAL_PMD_SIZE (1UL << SRMMU_REAL_PMD_SHIFT) +#define SRMMU_REAL_PMD_MASK (~(SRMMU_REAL_PMD_SIZE-1)) +#define SRMMU_REAL_PMD_ALIGN(__addr) (((__addr)+SRMMU_REAL_PMD_SIZE-1)&SRMMU_REAL_PMD_MASK) /* PGDIR_SHIFT determines what a third-level page table entry can map */ #define SRMMU_PGDIR_SHIFT 24 @@ -28,13 +28,13 @@ #define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1)) #define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK) -#define SRMMU_PTRS_PER_PTE 64 -#define SRMMU_PTRS_PER_PMD 64 -#define SRMMU_PTRS_PER_PGD 256 - -#define SRMMU_PTE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */ -#define SRMMU_PMD_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */ -#define SRMMU_PGD_TABLE_SIZE 0x400 /* 256 entries, 4 bytes a piece */ +#define SRMMU_REAL_PTRS_PER_PTE 64 +#define SRMMU_REAL_PTRS_PER_PMD 64 +#define SRMMU_PTRS_PER_PGD 256 + +#define SRMMU_REAL_PTE_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PTE*4) +#define SRMMU_PMD_TABLE_SIZE (SRMMU_REAL_PTRS_PER_PMD*4) +#define SRMMU_PGD_TABLE_SIZE (SRMMU_PTRS_PER_PGD*4) /* * To support pagetables in highmem, Linux introduces APIs which @@ -44,16 +44,11 @@ * software tables. * * PMD_SHIFT determines the size of the area a second-level page table entry - * can map, and our pmd_t is 16 times larger than normal. + * can map, and our pmd_t is 16 times larger than normal. The values which + * were once defined here are now generic for 4c and srmmu, so they're + * found in pgtable.h. */ -#define SRMMU_PTRS_PER_PTE_SOFT (PAGE_SIZE/4) /* 16 hard tables per 4K page */ -#define SRMMU_PTRS_PER_PMD_SOFT 4 /* Each pmd_t contains 16 hard PTPs */ -#define SRMMU_PTE_SZ_SOFT PAGE_SIZE /* same as above, in bytes */ - -#define SRMMU_PMD_SHIFT_SOFT 22 -#define SRMMU_PMD_SIZE_SOFT (1UL << SRMMU_PMD_SHIFT_SOFT) -#define SRMMU_PMD_MASK_SOFT (~(SRMMU_PMD_SIZE_SOFT-1)) -#define SRMMU_PMD_ALIGN_SOFT(addr) (((addr)+SRMMU_PMD_SIZE_SOFT-1)&SRMMU_PMD_MASK_SOFT) +#define SRMMU_PTRS_PER_PMD 4 /* Definition of the values in the ET field of PTD's and PTE's */ #define SRMMU_ET_MASK 0x3 @@ -255,7 +250,7 @@ extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr) { - addr &= SRMMU_PMD_MASK; + addr &= SRMMU_REAL_PMD_MASK; __asm__ __volatile__("sta %%g0, [%0] %1\n\t": : "r" (addr | 0x100), /* Flush TLB segment.. */ "i" (ASI_M_FLUSH_PROBE) : "memory"); diff -urN linux-2.6.7-rc3/include/asm-sparc/pgtsun4.h linux-2.6.7/include/asm-sparc/pgtsun4.h --- linux-2.6.7-rc3/include/asm-sparc/pgtsun4.h 2004-05-09 19:32:02.000000000 -0700 +++ linux-2.6.7/include/asm-sparc/pgtsun4.h 2004-06-15 23:10:47.947882611 -0700 @@ -11,9 +11,6 @@ /* PMD_SHIFT determines the size of the area a second-level page table can map */ #define SUN4C_PMD_SHIFT 23 -#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT) -#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1)) -#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK) /* PGDIR_SHIFT determines what a third-level page table entry can map */ #define SUN4C_PGDIR_SHIFT 23 diff -urN linux-2.6.7-rc3/include/asm-sparc/pgtsun4c.h linux-2.6.7/include/asm-sparc/pgtsun4c.h --- linux-2.6.7-rc3/include/asm-sparc/pgtsun4c.h 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/include/asm-sparc/pgtsun4c.h 2004-06-15 23:10:47.948882654 -0700 @@ -10,9 +10,6 @@ /* PMD_SHIFT determines the size of the area a second-level page table can map */ #define SUN4C_PMD_SHIFT 22 -#define SUN4C_PMD_SIZE (1UL << SUN4C_PMD_SHIFT) -#define SUN4C_PMD_MASK (~(SUN4C_PMD_SIZE-1)) -#define SUN4C_PMD_ALIGN(addr) (((addr)+SUN4C_PMD_SIZE-1)&SUN4C_PMD_MASK) /* PGDIR_SHIFT determines what a third-level page table entry can map */ #define SUN4C_PGDIR_SHIFT 22 diff -urN linux-2.6.7-rc3/include/asm-sparc/viking.h linux-2.6.7/include/asm-sparc/viking.h --- linux-2.6.7-rc3/include/asm-sparc/viking.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/asm-sparc/viking.h 2004-06-15 23:10:47.979883959 -0700 @@ -236,7 +236,7 @@ : "=r" (val) : "r" (vaddr | 0x100), "i" (ASI_M_FLUSH_PROBE)); if ((val & SRMMU_ET_MASK) == SRMMU_ET_PTE) { - vaddr &= ~SRMMU_PMD_MASK; + vaddr &= ~SRMMU_REAL_PMD_MASK; vaddr >>= PAGE_SHIFT; return val | (vaddr << 8); } diff -urN linux-2.6.7-rc3/include/asm-sparc64/bitops.h linux-2.6.7/include/asm-sparc64/bitops.h --- linux-2.6.7-rc3/include/asm-sparc64/bitops.h 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/include/asm-sparc64/bitops.h 2004-06-15 23:10:48.061887412 -0700 @@ -204,43 +204,7 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -static __inline__ unsigned long find_next_bit(unsigned long *addr, unsigned long size, unsigned long offset) -{ - unsigned long *p = addr + (offset >> 6); - unsigned long result = offset & ~63UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 63UL; - if (offset) { - tmp = *(p++); - tmp &= (~0UL << offset); - if (size < 64) - goto found_first; - if (tmp) - goto found_middle; - size -= 64; - result += 64; - } - while (size & ~63UL) { - if ((tmp = *(p++))) - goto found_middle; - result += 64; - size -= 64; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp &= (~0UL >> (64 - size)); - if (tmp == 0UL) /* Are any bits set? */ - return result + size; /* Nope. */ -found_middle: - return result + __ffs(tmp); -} +extern unsigned long find_next_bit(unsigned long *, unsigned long, unsigned long); /** * find_first_bit - find the first set bit in a memory region @@ -258,43 +222,7 @@ * on Linus's ALPHA routines, which are pretty portable BTW. */ -static __inline__ unsigned long find_next_zero_bit(unsigned long *addr, unsigned long size, unsigned long offset) -{ - unsigned long *p = addr + (offset >> 6); - unsigned long result = offset & ~63UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 63UL; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (64-offset); - if (size < 64) - goto found_first; - if (~tmp) - goto found_middle; - size -= 64; - result += 64; - } - while (size & ~63UL) { - if (~(tmp = *(p++))) - goto found_middle; - result += 64; - size -= 64; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp |= ~0UL << size; - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} +extern unsigned long find_next_zero_bit(unsigned long *, unsigned long, unsigned long); #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) @@ -320,42 +248,7 @@ #define find_first_zero_le_bit(addr, size) \ find_next_zero_le_bit((addr), (size), 0) -static __inline__ unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset) -{ - unsigned long *p = addr + (offset >> 6); - unsigned long result = offset & ~63UL; - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 63UL; - if(offset) { - tmp = __swab64p(p++); - tmp |= (~0UL >> (64-offset)); - if(size < 64) - goto found_first; - if(~tmp) - goto found_middle; - size -= 64; - result += 64; - } - while(size & ~63) { - if(~(tmp = __swab64p(p++))) - goto found_middle; - result += 64; - size -= 64; - } - if(!size) - return result; - tmp = __swab64p(p); -found_first: - tmp |= (~0UL << size); - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} +extern unsigned long find_next_zero_le_bit(unsigned long *, unsigned long, unsigned long); #ifdef __KERNEL__ diff -urN linux-2.6.7-rc3/include/asm-um/unistd.h linux-2.6.7/include/asm-um/unistd.h --- linux-2.6.7-rc3/include/asm-um/unistd.h 2004-06-15 23:10:02.580972661 -0700 +++ linux-2.6.7/include/asm-um/unistd.h 2004-06-15 23:10:48.337899035 -0700 @@ -34,6 +34,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-v850/unistd.h linux-2.6.7/include/asm-v850/unistd.h --- linux-2.6.7-rc3/include/asm-v850/unistd.h 2004-06-15 23:10:02.583972787 -0700 +++ linux-2.6.7/include/asm-v850/unistd.h 2004-06-15 23:10:48.592909773 -0700 @@ -408,6 +408,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifdef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/asm-x86_64/i387.h linux-2.6.7/include/asm-x86_64/i387.h --- linux-2.6.7-rc3/include/asm-x86_64/i387.h 2004-06-15 23:10:02.586972913 -0700 +++ linux-2.6.7/include/asm-x86_64/i387.h 2004-06-15 23:10:48.805918743 -0700 @@ -48,7 +48,7 @@ #define clear_fpu(tsk) do { \ if ((tsk)->thread_info->status & TS_USEDFPU) { \ - asm volatile("fwait"); \ + asm volatile("fnclex ; fwait"); \ (tsk)->thread_info->status &= ~TS_USEDFPU; \ stts(); \ } \ diff -urN linux-2.6.7-rc3/include/asm-x86_64/unistd.h linux-2.6.7/include/asm-x86_64/unistd.h --- linux-2.6.7-rc3/include/asm-x86_64/unistd.h 2004-06-15 23:10:02.594973250 -0700 +++ linux-2.6.7/include/asm-x86_64/unistd.h 2004-06-15 23:10:49.003927081 -0700 @@ -591,6 +591,7 @@ #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION #endif #ifndef __KERNEL_SYSCALLS__ diff -urN linux-2.6.7-rc3/include/linux/cpumask.h linux-2.6.7/include/linux/cpumask.h --- linux-2.6.7-rc3/include/linux/cpumask.h 2004-06-15 23:10:02.603973629 -0700 +++ linux-2.6.7/include/linux/cpumask.h 2004-06-15 23:10:49.508948347 -0700 @@ -41,6 +41,7 @@ #define cpu_possible(cpu) ({ BUG_ON((cpu) != 0); 1; }) #define cpu_present(cpu) ({ BUG_ON((cpu) != 0); 1; }) +#define for_each_cpu_mask(cpu, mask) for (cpu = 0; cpu < 1; cpu++) #define for_each_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #define for_each_online_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) #define for_each_present_cpu(cpu) for (cpu = 0; cpu < 1; cpu++) diff -urN linux-2.6.7-rc3/include/linux/ethtool.h linux-2.6.7/include/linux/ethtool.h --- linux-2.6.7-rc3/include/linux/ethtool.h 2004-05-09 19:32:26.000000000 -0700 +++ linux-2.6.7/include/linux/ethtool.h 2004-06-15 23:10:49.622953148 -0700 @@ -351,6 +351,8 @@ int (*phys_id)(struct net_device *, u32); int (*get_stats_count)(struct net_device *); void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *); + int (*begin)(struct net_device *); + void (*complete)(struct net_device *); }; /* CMDs currently supported */ diff -urN linux-2.6.7-rc3/include/linux/ipv6.h linux-2.6.7/include/linux/ipv6.h --- linux-2.6.7-rc3/include/linux/ipv6.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/linux/ipv6.h 2004-06-15 23:10:50.230978752 -0700 @@ -192,6 +192,8 @@ __u16 dst1; }; +#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb)) + struct ipv6_pinfo { struct in6_addr saddr; struct in6_addr rcv_saddr; diff -urN linux-2.6.7-rc3/include/linux/kmod.h linux-2.6.7/include/linux/kmod.h --- linux-2.6.7-rc3/include/linux/kmod.h 2004-05-09 19:32:02.000000000 -0700 +++ linux-2.6.7/include/linux/kmod.h 2004-06-15 23:10:50.286981110 -0700 @@ -23,6 +23,8 @@ #include #include +#define KMOD_PATH_LEN 256 + #ifdef CONFIG_KMOD /* modprobe exit status on success, -ve on error. Return value * usually useless though. */ diff -urN linux-2.6.7-rc3/include/linux/netfilter_arp.h linux-2.6.7/include/linux/netfilter_arp.h --- linux-2.6.7-rc3/include/linux/netfilter_arp.h 2004-06-15 23:10:02.698977628 -0700 +++ linux-2.6.7/include/linux/netfilter_arp.h 2004-05-09 19:32:00.000000000 -0700 @@ -17,5 +17,4 @@ #define NF_ARP_FORWARD 2 #define NF_ARP_NUMHOOKS 3 -static DECLARE_MUTEX(arpt_mutex); #endif /* __LINUX_ARP_NETFILTER_H */ diff -urN linux-2.6.7-rc3/include/linux/page-flags.h linux-2.6.7/include/linux/page-flags.h --- linux-2.6.7-rc3/include/linux/page-flags.h 2004-06-15 23:10:02.702977796 -0700 +++ linux-2.6.7/include/linux/page-flags.h 2004-06-15 23:10:50.487989575 -0700 @@ -133,12 +133,16 @@ unsigned long allocstall; /* direct reclaim calls */ unsigned long pgrotated; /* pages rotated to tail of the LRU */ -} ____cacheline_aligned; +}; DECLARE_PER_CPU(struct page_state, page_states); extern void get_page_state(struct page_state *ret); extern void get_full_page_state(struct page_state *ret); +extern unsigned long __read_page_state(unsigned offset); + +#define read_page_state(member) \ + __read_page_state(offsetof(struct page_state, member)) #define mod_page_state(member, delta) \ do { \ diff -urN linux-2.6.7-rc3/include/linux/pci_ids.h linux-2.6.7/include/linux/pci_ids.h --- linux-2.6.7-rc3/include/linux/pci_ids.h 2004-06-15 23:10:02.705977922 -0700 +++ linux-2.6.7/include/linux/pci_ids.h 2004-06-15 23:10:50.513990670 -0700 @@ -730,6 +730,7 @@ #define PCI_DEVICE_ID_TI_1410 0xac50 #define PCI_DEVICE_ID_TI_1420 0xac51 #define PCI_DEVICE_ID_TI_1451A 0xac52 +#define PCI_DEVICE_ID_TI_1620 0xac54 #define PCI_DEVICE_ID_TI_1520 0xac55 #define PCI_DEVICE_ID_TI_1510 0xac56 @@ -1853,8 +1854,11 @@ #define PCI_DEVICE_ID_TIGON3_5750 0x1676 #define PCI_DEVICE_ID_TIGON3_5751 0x1677 #define PCI_DEVICE_ID_TIGON3_5750M 0x167c +#define PCI_DEVICE_ID_TIGON3_5751M 0x167d +#define PCI_DEVICE_ID_TIGON3_5751F 0x167e #define PCI_DEVICE_ID_TIGON3_5782 0x1696 #define PCI_DEVICE_ID_TIGON3_5788 0x169c +#define PCI_DEVICE_ID_TIGON3_5789 0x169d #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 diff -urN linux-2.6.7-rc3/include/linux/sched.h linux-2.6.7/include/linux/sched.h --- linux-2.6.7-rc3/include/linux/sched.h 2004-06-15 23:10:02.716978385 -0700 +++ linux-2.6.7/include/linux/sched.h 2004-06-15 23:10:50.718999303 -0700 @@ -738,7 +738,7 @@ static inline void kick_process(struct task_struct *tsk) { } static inline void wake_up_forked_thread(struct task_struct * tsk) { - return wake_up_forked_process(tsk); + wake_up_forked_process(tsk); } #endif extern void FASTCALL(sched_fork(task_t * p)); diff -urN linux-2.6.7-rc3/include/linux/security.h linux-2.6.7/include/linux/security.h --- linux-2.6.7-rc3/include/linux/security.h 2004-05-09 19:32:54.000000000 -0700 +++ linux-2.6.7/include/linux/security.h 2004-06-15 23:10:50.819003514 -0700 @@ -1172,7 +1172,7 @@ int (*shm_associate) (struct shmid_kernel * shp, int shmflg); int (*shm_shmctl) (struct shmid_kernel * shp, int cmd); int (*shm_shmat) (struct shmid_kernel * shp, - char *shmaddr, int shmflg); + char __user *shmaddr, int shmflg); int (*sem_alloc_security) (struct sem_array * sma); void (*sem_free_security) (struct sem_array * sma); diff -urN linux-2.6.7-rc3/include/linux/stat.h linux-2.6.7/include/linux/stat.h --- linux-2.6.7-rc3/include/linux/stat.h 2004-05-09 19:32:27.000000000 -0700 +++ linux-2.6.7/include/linux/stat.h 2004-06-15 23:10:50.868005577 -0700 @@ -60,7 +60,7 @@ unsigned long ino; dev_t dev; umode_t mode; - nlink_t nlink; + unsigned int nlink; uid_t uid; gid_t gid; dev_t rdev; diff -urN linux-2.6.7-rc3/include/linux/tcp.h linux-2.6.7/include/linux/tcp.h --- linux-2.6.7-rc3/include/linux/tcp.h 2004-06-15 23:10:02.726978806 -0700 +++ linux-2.6.7/include/linux/tcp.h 2004-06-15 23:10:50.956009283 -0700 @@ -183,6 +183,9 @@ __u32 tcpi_snd_cwnd; __u32 tcpi_advmss; __u32 tcpi_reordering; + + __u32 tcpi_rcv_rtt; + __u32 tcpi_rcv_space; }; #ifdef __KERNEL__ @@ -351,11 +354,11 @@ __u8 urg_mode; /* In urgent mode */ __u32 snd_up; /* Urgent pointer */ - /* The syn_wait_lock is necessary only to avoid tcp_get_info having + /* The syn_wait_lock is necessary only to avoid proc interface having * to grab the main lock sock while browsing the listening hash * (otherwise it's deadlock prone). - * This lock is acquired in read mode only from tcp_get_info() and - * it's acquired in write mode _only_ from code that is actively + * This lock is acquired in read mode only from listening_get_next() + * and it's acquired in write mode _only_ from code that is actively * changing the syn_wait_queue. All readers that are holding * the master sock lock don't need to grab this lock in read mode * too as the syn_wait_queue writes are always protected from diff -urN linux-2.6.7-rc3/include/linux/udf_fs.h linux-2.6.7/include/linux/udf_fs.h --- linux-2.6.7-rc3/include/linux/udf_fs.h 2004-05-09 19:32:01.000000000 -0700 +++ linux-2.6.7/include/linux/udf_fs.h 2004-06-15 23:10:50.980010294 -0700 @@ -40,7 +40,7 @@ #define UDFFS_DATE "2004/29/09" #define UDFFS_VERSION "0.9.8.1" -#define UDFFS_DEBUG +#undef UDFFS_DEBUG #ifdef UDFFS_DEBUG #define udf_debug(f, a...) \ diff -urN linux-2.6.7-rc3/include/linux/usb.h linux-2.6.7/include/linux/usb.h --- linux-2.6.7-rc3/include/linux/usb.h 2004-06-15 23:10:02.730978975 -0700 +++ linux-2.6.7/include/linux/usb.h 2004-06-15 23:10:50.982010378 -0700 @@ -334,6 +334,7 @@ /* mostly for devices emulating SCSI over USB */ extern int usb_reset_device(struct usb_device *dev); +extern int __usb_reset_device(struct usb_device *dev); extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); diff -urN linux-2.6.7-rc3/include/net/dst.h linux-2.6.7/include/net/dst.h --- linux-2.6.7-rc3/include/net/dst.h 2004-06-15 23:10:02.738979311 -0700 +++ linux-2.6.7/include/net/dst.h 2004-06-15 23:10:51.216020232 -0700 @@ -89,6 +89,7 @@ int (*gc)(void); struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); void (*destroy)(struct dst_entry *); + void (*ifdown)(struct dst_entry *, int how); struct dst_entry * (*negative_advice)(struct dst_entry *); void (*link_failure)(struct sk_buff *); void (*update_pmtu)(struct dst_entry *dst, u32 mtu); diff -urN linux-2.6.7-rc3/include/net/ipv6.h linux-2.6.7/include/net/ipv6.h --- linux-2.6.7-rc3/include/net/ipv6.h 2004-06-15 23:10:02.740979396 -0700 +++ linux-2.6.7/include/net/ipv6.h 2004-06-15 23:10:51.243021370 -0700 @@ -356,7 +356,6 @@ */ extern int ip6_output(struct sk_buff **pskb); -extern int ip6_output2(struct sk_buff **pskb); extern int ip6_forward(struct sk_buff *skb); extern int ip6_input(struct sk_buff *skb); extern int ip6_mc_input(struct sk_buff *skb); diff -urN linux-2.6.7-rc3/include/net/sock.h linux-2.6.7/include/net/sock.h --- linux-2.6.7-rc3/include/net/sock.h 2004-06-15 23:10:02.747979690 -0700 +++ linux-2.6.7/include/net/sock.h 2004-06-15 23:10:51.441029708 -0700 @@ -398,6 +398,21 @@ return test_bit(flag, &sk->sk_flags); } +static inline void sk_acceptq_removed(struct sock *sk) +{ + sk->sk_ack_backlog--; +} + +static inline void sk_acceptq_added(struct sock *sk) +{ + sk->sk_ack_backlog++; +} + +static inline int sk_acceptq_is_full(struct sock *sk) +{ + return sk->sk_ack_backlog > sk->sk_max_ack_backlog; +} + /* The per-socket spinlock must be held here. */ #define sk_add_backlog(__sk, __skb) \ do { if (!(__sk)->sk_backlog.tail) { \ @@ -410,6 +425,20 @@ (__skb)->next = NULL; \ } while(0) +#define sk_wait_event(__sk, __timeo, __condition) \ +({ int rc; \ + release_sock(__sk); \ + rc = __condition; \ + if (!rc) { \ + *(__timeo) = schedule_timeout(*(__timeo)); \ + rc = __condition; \ + } \ + lock_sock(__sk); \ + rc; \ +}) + +extern int sk_wait_data(struct sock *sk, long *timeo); + /* IP protocol blocks we attach to sockets. * socket layer -> transport layer interface * transport -> network interface is defined by struct inet_proto @@ -898,6 +927,11 @@ atomic_add(skb->truesize, &sk->sk_rmem_alloc); } +extern void sk_reset_timer(struct sock *sk, struct timer_list* timer, + unsigned long expires); + +extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); + static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -1035,6 +1069,20 @@ sk->sk_stamp = *stamp; } +/** + * sk_eat_skb - Release a skb if it is no longer needed + * @sk - socket to eat this skb from + * @skb - socket buffer to eat + * + * This routine must be called with interrupts disabled or with the socket + * locked so that the sk_buff queue operation is ok. +*/ +static inline void sk_eat_skb(struct sock *sk, struct sk_buff *skb) +{ + __skb_unlink(skb, &sk->sk_receive_queue); + __kfree_skb(skb); +} + extern atomic_t netstamp_needed; extern void sock_enable_timestamp(struct sock *sk); extern void sock_disable_timestamp(struct sock *sk); diff -urN linux-2.6.7-rc3/include/net/tcp.h linux-2.6.7/include/net/tcp.h --- linux-2.6.7-rc3/include/net/tcp.h 2004-06-15 23:10:02.749979774 -0700 +++ linux-2.6.7/include/net/tcp.h 2004-06-15 23:10:51.475031140 -0700 @@ -989,9 +989,7 @@ tp->pending = 0; #ifdef TCP_CLEAR_TIMERS - if (timer_pending(&tp->retransmit_timer) && - del_timer(&tp->retransmit_timer)) - __sock_put(sk); + sk_stop_timer(sk, &tp->retransmit_timer); #endif break; case TCP_TIME_DACK: @@ -999,9 +997,7 @@ tp->ack.pending = 0; #ifdef TCP_CLEAR_TIMERS - if (timer_pending(&tp->delack_timer) && - del_timer(&tp->delack_timer)) - __sock_put(sk); + sk_stop_timer(sk, &tp->delack_timer); #endif break; default: @@ -1030,15 +1026,13 @@ case TCP_TIME_PROBE0: tp->pending = what; tp->timeout = jiffies+when; - if (!mod_timer(&tp->retransmit_timer, tp->timeout)) - sock_hold(sk); + sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout); break; case TCP_TIME_DACK: tp->ack.pending |= TCP_ACK_TIMER; tp->ack.timeout = jiffies+when; - if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) - sock_hold(sk); + sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout); break; default: @@ -1800,28 +1794,13 @@ return tcp_win_from_space(sk->sk_rcvbuf); } -static inline void tcp_acceptq_removed(struct sock *sk) -{ - sk->sk_ack_backlog--; -} - -static inline void tcp_acceptq_added(struct sock *sk) -{ - sk->sk_ack_backlog++; -} - -static inline int tcp_acceptq_is_full(struct sock *sk) -{ - return sk->sk_ack_backlog > sk->sk_max_ack_backlog; -} - static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req, struct sock *child) { struct tcp_opt *tp = tcp_sk(sk); req->sk = child; - tcp_acceptq_added(sk); + sk_acceptq_added(sk); if (!tp->accept_queue_tail) { tp->accept_queue = req; diff -urN linux-2.6.7-rc3/kernel/exit.c linux-2.6.7/kernel/exit.c --- linux-2.6.7-rc3/kernel/exit.c 2004-06-15 23:10:03.708020099 -0700 +++ linux-2.6.7/kernel/exit.c 2004-06-15 23:10:52.297065756 -0700 @@ -740,7 +740,7 @@ * Clear these here so that update_process_times() won't try to deliver * itimer, profile or rlimit signals to this task while it is in late exit. */ - tsk->it_virt_incr = 0; + tsk->it_virt_value = 0; tsk->it_prof_value = 0; tsk->rlim[RLIMIT_CPU].rlim_cur = RLIM_INFINITY; diff -urN linux-2.6.7-rc3/kernel/fork.c linux-2.6.7/kernel/fork.c --- linux-2.6.7-rc3/kernel/fork.c 2004-06-15 23:10:03.792023635 -0700 +++ linux-2.6.7/kernel/fork.c 2004-06-15 23:10:52.360068409 -0700 @@ -271,7 +271,7 @@ struct vm_area_struct * mpnt, *tmp, **pprev; struct rb_node **rb_link, *rb_parent; int retval; - unsigned long charge = 0; + unsigned long charge; struct mempolicy *pol; down_write(&oldmm->mmap_sem); @@ -304,11 +304,12 @@ if(mpnt->vm_flags & VM_DONTCOPY) continue; + charge = 0; if (mpnt->vm_flags & VM_ACCOUNT) { unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; if (security_vm_enough_memory(len)) goto fail_nomem; - charge += len; + charge = len; } tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!tmp) @@ -360,7 +361,7 @@ tmp->vm_ops->open(tmp); if (retval) - goto fail; + goto out; } retval = 0; @@ -372,10 +373,10 @@ kmem_cache_free(vm_area_cachep, tmp); fail_nomem: retval = -ENOMEM; -fail: vm_unacct_memory(charge); goto out; } + static inline int mm_alloc_pgd(struct mm_struct * mm) { mm->pgd = pgd_alloc(mm); diff -urN linux-2.6.7-rc3/kernel/kmod.c linux-2.6.7/kernel/kmod.c --- linux-2.6.7-rc3/kernel/kmod.c 2004-06-15 23:10:03.854026245 -0700 +++ linux-2.6.7/kernel/kmod.c 2004-06-15 23:10:52.378069167 -0700 @@ -47,7 +47,7 @@ /* modprobe_path is set via /proc/sys. */ -char modprobe_path[256] = "/sbin/modprobe"; +char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; /** * request_module - try to load a kernel module @@ -132,7 +132,7 @@ events. the command is expected to load drivers when necessary, and may perform additional system setup. */ -char hotplug_path[256] = "/sbin/hotplug"; +char hotplug_path[KMOD_PATH_LEN] = "/sbin/hotplug"; EXPORT_SYMBOL(hotplug_path); diff -urN linux-2.6.7-rc3/kernel/resource.c linux-2.6.7/kernel/resource.c --- linux-2.6.7-rc3/kernel/resource.c 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/kernel/resource.c 2004-06-15 23:10:52.470073042 -0700 @@ -332,8 +332,8 @@ if (next->sibling->start > new->end) break; - /* existing resource overlaps end of new resource */ - if (next->end > new->end) { + /* existing resource includes new resource */ + if (next->end >= new->end) { parent = next; result = 0; goto begin; diff -urN linux-2.6.7-rc3/kernel/sched.c linux-2.6.7/kernel/sched.c --- linux-2.6.7-rc3/kernel/sched.c 2004-06-15 23:10:04.048034411 -0700 +++ linux-2.6.7/kernel/sched.c 2004-06-15 23:10:52.484073631 -0700 @@ -770,8 +770,7 @@ this_load -= SCHED_LOAD_SCALE; /* Don't pull the task off an idle CPU to a busy one */ - if (load < SCHED_LOAD_SCALE && load + this_load > SCHED_LOAD_SCALE - && this_load > load) + if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2) goto out_set_cpu; new_cpu = this_cpu; /* Wake to this CPU if we can */ @@ -1633,7 +1632,8 @@ return busiest; out_balanced: - if (busiest && idle != NOT_IDLE && max_load > SCHED_LOAD_SCALE) { + if (busiest && (idle == NEWLY_IDLE || + (idle == IDLE && max_load > SCHED_LOAD_SCALE)) ) { *imbalance = 1; return busiest; } diff -urN linux-2.6.7-rc3/kernel/signal.c linux-2.6.7/kernel/signal.c --- linux-2.6.7-rc3/kernel/signal.c 2004-06-15 23:10:04.058034832 -0700 +++ linux-2.6.7/kernel/signal.c 2004-06-15 23:10:52.487073758 -0700 @@ -2477,7 +2477,7 @@ } #endif /* __ARCH_WANT_SYS_SIGPROCMASK */ -#ifndef __sparc__ +#ifdef __ARCH_WANT_SYS_RT_SIGACTION asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, @@ -2505,7 +2505,7 @@ out: return ret; } -#endif /* __sparc__ */ +#endif /* __ARCH_WANT_SYS_RT_SIGACTION */ #ifdef __ARCH_WANT_SYS_SGETMASK diff -urN linux-2.6.7-rc3/kernel/sysctl.c linux-2.6.7/kernel/sysctl.c --- linux-2.6.7-rc3/kernel/sysctl.c 2004-06-15 23:10:04.063035042 -0700 +++ linux-2.6.7/kernel/sysctl.c 2004-06-15 23:10:52.528075484 -0700 @@ -218,7 +218,7 @@ .ctl_name = KERN_OSTYPE, .procname = "ostype", .data = system_utsname.sysname, - .maxlen = 64, + .maxlen = sizeof(system_utsname.sysname), .mode = 0444, .proc_handler = &proc_doutsstring, .strategy = &sysctl_string, @@ -227,7 +227,7 @@ .ctl_name = KERN_OSRELEASE, .procname = "osrelease", .data = system_utsname.release, - .maxlen = 64, + .maxlen = sizeof(system_utsname.release), .mode = 0444, .proc_handler = &proc_doutsstring, .strategy = &sysctl_string, @@ -236,7 +236,7 @@ .ctl_name = KERN_VERSION, .procname = "version", .data = system_utsname.version, - .maxlen = 64, + .maxlen = sizeof(system_utsname.version), .mode = 0444, .proc_handler = &proc_doutsstring, .strategy = &sysctl_string, @@ -245,7 +245,7 @@ .ctl_name = KERN_NODENAME, .procname = "hostname", .data = system_utsname.nodename, - .maxlen = 64, + .maxlen = sizeof(system_utsname.nodename), .mode = 0644, .proc_handler = &proc_doutsstring, .strategy = &sysctl_string, @@ -254,7 +254,7 @@ .ctl_name = KERN_DOMAINNAME, .procname = "domainname", .data = system_utsname.domainname, - .maxlen = 64, + .maxlen = sizeof(system_utsname.domainname), .mode = 0644, .proc_handler = &proc_doutsstring, .strategy = &sysctl_string, @@ -392,7 +392,7 @@ .ctl_name = KERN_MODPROBE, .procname = "modprobe", .data = &modprobe_path, - .maxlen = 256, + .maxlen = KMOD_PATH_LEN, .mode = 0644, .proc_handler = &proc_dostring, .strategy = &sysctl_string, @@ -403,7 +403,7 @@ .ctl_name = KERN_HOTPLUG, .procname = "hotplug", .data = &hotplug_path, - .maxlen = 256, + .maxlen = KMOD_PATH_LEN, .mode = 0644, .proc_handler = &proc_dostring, .strategy = &sysctl_string, @@ -1917,56 +1917,56 @@ #else /* CONFIG_PROC_FS */ int proc_dostring(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } static int proc_doutsstring(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } @@ -2141,13 +2141,13 @@ } int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) + void __user *buffer, size_t *lenp) { return -ENOSYS; } diff -urN linux-2.6.7-rc3/kernel/workqueue.c linux-2.6.7/kernel/workqueue.c --- linux-2.6.7-rc3/kernel/workqueue.c 2004-06-15 23:10:04.065035127 -0700 +++ linux-2.6.7/kernel/workqueue.c 2004-06-15 23:10:52.531075611 -0700 @@ -218,6 +218,33 @@ return 0; } +static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) +{ + if (cwq->thread == current) { + /* + * Probably keventd trying to flush its own queue. So simply run + * it by hand rather than deadlocking. + */ + run_workqueue(cwq); + } else { + DEFINE_WAIT(wait); + long sequence_needed; + + spin_lock_irq(&cwq->lock); + sequence_needed = cwq->insert_sequence; + + while (sequence_needed - cwq->remove_sequence > 0) { + prepare_to_wait(&cwq->work_done, &wait, + TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&cwq->lock); + schedule(); + spin_lock_irq(&cwq->lock); + } + finish_wait(&cwq->work_done, &wait); + spin_unlock_irq(&cwq->lock); + } +} + /* * flush_workqueue - ensure that any scheduled work has run to completion. * @@ -234,43 +261,19 @@ */ void fastcall flush_workqueue(struct workqueue_struct *wq) { - struct cpu_workqueue_struct *cwq; - int cpu; - might_sleep(); - lock_cpu_hotplug(); - for_each_online_cpu(cpu) { - DEFINE_WAIT(wait); - long sequence_needed; - - if (is_single_threaded(wq)) - cwq = wq->cpu_wq + 0; /* Always use cpu 0's area. */ - else - cwq = wq->cpu_wq + cpu; - - if (cwq->thread == current) { - /* - * Probably keventd trying to flush its own queue. - * So simply run it by hand rather than deadlocking. - */ - run_workqueue(cwq); - continue; - } - spin_lock_irq(&cwq->lock); - sequence_needed = cwq->insert_sequence; + if (is_single_threaded(wq)) { + /* Always use cpu 0's area. */ + flush_cpu_workqueue(wq->cpu_wq + 0); + } else { + int cpu; - while (sequence_needed - cwq->remove_sequence > 0) { - prepare_to_wait(&cwq->work_done, &wait, - TASK_UNINTERRUPTIBLE); - spin_unlock_irq(&cwq->lock); - schedule(); - spin_lock_irq(&cwq->lock); - } - finish_wait(&cwq->work_done, &wait); - spin_unlock_irq(&cwq->lock); + lock_cpu_hotplug(); + for_each_online_cpu(cpu) + flush_cpu_workqueue(wq->cpu_wq + cpu); + unlock_cpu_hotplug(); } - unlock_cpu_hotplug(); } static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq, diff -urN linux-2.6.7-rc3/lib/rwsem.c linux-2.6.7/lib/rwsem.c --- linux-2.6.7-rc3/lib/rwsem.c 2004-05-09 19:31:59.000000000 -0700 +++ linux-2.6.7/lib/rwsem.c 2004-06-15 23:10:52.638080117 -0700 @@ -29,15 +29,15 @@ /* * handle the lock being released whilst there are processes blocked on it that can now run - * - if we come here, then: - * - the 'active part' of the count (&0x0000ffff) reached zero but has been re-incremented + * - if we come here from up_xxxx(), then: + * - the 'active part' of the count (&0x0000ffff) had reached zero (but may have changed) * - the 'waiting part' of the count (&0xffff0000) is negative (and will still be so) * - there must be someone on the queue * - the spinlock must be held by the caller * - woken process blocks are discarded from the list after having task zeroed - * - writers are only woken if wakewrite is non-zero + * - writers are only woken if downgrading is false */ -static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) +static inline struct rw_semaphore *__rwsem_do_wake(struct rw_semaphore *sem, int downgrading) { struct rwsem_waiter *waiter; struct task_struct *tsk; @@ -46,10 +46,12 @@ rwsemtrace(sem,"Entering __rwsem_do_wake"); - if (!wakewrite) + if (downgrading) goto dont_wake_writers; - /* only wake someone up if we can transition the active part of the count from 0 -> 1 */ + /* if we came through an up_xxxx() call, we only only wake someone up + * if we can transition the active part of the count from 0 -> 1 + */ try_again: oldcount = rwsem_atomic_update(RWSEM_ACTIVE_BIAS,sem) - RWSEM_ACTIVE_BIAS; if (oldcount & RWSEM_ACTIVE_MASK) @@ -78,9 +80,10 @@ if (waiter->flags & RWSEM_WAITING_FOR_WRITE) goto out; - /* grant an infinite number of read locks to the readers at the front of the queue - * - note we increment the 'active part' of the count by the number of readers (less one - * for the activity decrement we've already done) before waking any processes up + /* grant an infinite number of read locks to the readers at the front + * of the queue + * - note we increment the 'active part' of the count by the number of + * readers before waking any processes up */ readers_only: woken = 0; @@ -95,8 +98,10 @@ } while (waiter->flags & RWSEM_WAITING_FOR_READ); loop = woken; - woken *= RWSEM_ACTIVE_BIAS-RWSEM_WAITING_BIAS; - woken -= RWSEM_ACTIVE_BIAS; + woken *= RWSEM_ACTIVE_BIAS - RWSEM_WAITING_BIAS; + if (!downgrading) + woken -= RWSEM_ACTIVE_BIAS; /* we'd already done one increment + * earlier */ rwsem_atomic_add(woken,sem); next = sem->wait_list.next; @@ -150,7 +155,7 @@ * - it might even be this process, since the waker takes a more active part */ if (!(count & RWSEM_ACTIVE_MASK)) - sem = __rwsem_do_wake(sem,1); + sem = __rwsem_do_wake(sem, 0); spin_unlock(&sem->wait_lock); @@ -201,7 +206,7 @@ /* * handle waking up a waiter on the semaphore - * - up_read has decremented the active part of the count if we come here + * - up_read/up_write has decremented the active part of the count if we come here */ struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) { @@ -211,7 +216,7 @@ /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) - sem = __rwsem_do_wake(sem,1); + sem = __rwsem_do_wake(sem, 0); spin_unlock(&sem->wait_lock); @@ -233,7 +238,7 @@ /* do nothing if list empty */ if (!list_empty(&sem->wait_list)) - sem = __rwsem_do_wake(sem,0); + sem = __rwsem_do_wake(sem, 1); spin_unlock(&sem->wait_lock); diff -urN linux-2.6.7-rc3/mm/mempolicy.c linux-2.6.7/mm/mempolicy.c --- linux-2.6.7-rc3/mm/mempolicy.c 2004-06-15 23:10:04.503053563 -0700 +++ linux-2.6.7/mm/mempolicy.c 2004-06-15 23:10:52.803087065 -0700 @@ -61,6 +61,7 @@ #include #include +#include #include #include #include diff -urN linux-2.6.7-rc3/mm/page-writeback.c linux-2.6.7/mm/page-writeback.c --- linux-2.6.7-rc3/mm/page-writeback.c 2004-06-15 23:10:04.549055500 -0700 +++ linux-2.6.7/mm/page-writeback.c 2004-06-15 23:10:52.821087823 -0700 @@ -99,6 +99,22 @@ static void background_writeout(unsigned long _min_pages); +struct writeback_state +{ + unsigned long nr_dirty; + unsigned long nr_unstable; + unsigned long nr_mapped; + unsigned long nr_writeback; +}; + +static void get_writeback_state(struct writeback_state *wbs) +{ + wbs->nr_dirty = read_page_state(nr_dirty); + wbs->nr_unstable = read_page_state(nr_unstable); + wbs->nr_mapped = read_page_state(nr_mapped); + wbs->nr_writeback = read_page_state(nr_writeback); +} + /* * Work out the current dirty-memory clamping and background writeout * thresholds. @@ -117,7 +133,7 @@ * clamping level. */ static void -get_dirty_limits(struct page_state *ps, long *pbackground, long *pdirty) +get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty) { int background_ratio; /* Percentages */ int dirty_ratio; @@ -126,9 +142,9 @@ long dirty; struct task_struct *tsk; - get_page_state(ps); + get_writeback_state(wbs); - unmapped_ratio = 100 - (ps->nr_mapped * 100) / total_pages; + unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages; dirty_ratio = vm_dirty_ratio; if (dirty_ratio > unmapped_ratio / 2) @@ -161,7 +177,7 @@ */ static void balance_dirty_pages(struct address_space *mapping) { - struct page_state ps; + struct writeback_state wbs; long nr_reclaimable; long background_thresh; long dirty_thresh; @@ -178,9 +194,9 @@ .nr_to_write = write_chunk, }; - get_dirty_limits(&ps, &background_thresh, &dirty_thresh); - nr_reclaimable = ps.nr_dirty + ps.nr_unstable; - if (nr_reclaimable + ps.nr_writeback <= dirty_thresh) + get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); + nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable; + if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh) break; dirty_exceeded = 1; @@ -193,10 +209,10 @@ */ if (nr_reclaimable) { writeback_inodes(&wbc); - get_dirty_limits(&ps, &background_thresh, + get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); - nr_reclaimable = ps.nr_dirty + ps.nr_unstable; - if (nr_reclaimable + ps.nr_writeback <= dirty_thresh) + nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable; + if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh) break; pages_written += write_chunk - wbc.nr_to_write; if (pages_written >= write_chunk) @@ -205,7 +221,7 @@ blk_congestion_wait(WRITE, HZ/10); } - if (nr_reclaimable + ps.nr_writeback <= dirty_thresh) + if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh) dirty_exceeded = 0; if (writeback_in_progress(bdi)) @@ -232,10 +248,10 @@ * which was newly dirtied. The function will periodically check the system's * dirty state and will initiate writeback if needed. * - * On really big machines, get_page_state is expensive, so try to avoid calling - * it too often (ratelimiting). But once we're over the dirty memory limit we - * decrease the ratelimiting by a lot, to prevent individual processes from - * overshooting the limit by (ratelimit_pages) each. + * On really big machines, get_writeback_state is expensive, so try to avoid + * calling it too often (ratelimiting). But once we're over the dirty memory + * limit we decrease the ratelimiting by a lot, to prevent individual processes + * from overshooting the limit by (ratelimit_pages) each. */ void balance_dirty_pages_ratelimited(struct address_space *mapping) { @@ -276,12 +292,12 @@ }; for ( ; ; ) { - struct page_state ps; + struct writeback_state wbs; long background_thresh; long dirty_thresh; - get_dirty_limits(&ps, &background_thresh, &dirty_thresh); - if (ps.nr_dirty + ps.nr_unstable < background_thresh + get_dirty_limits(&wbs, &background_thresh, &dirty_thresh); + if (wbs.nr_dirty + wbs.nr_unstable < background_thresh && min_pages <= 0) break; wbc.encountered_congestion = 0; @@ -306,10 +322,10 @@ int wakeup_bdflush(long nr_pages) { if (nr_pages == 0) { - struct page_state ps; + struct writeback_state wbs; - get_page_state(&ps); - nr_pages = ps.nr_dirty + ps.nr_unstable; + get_writeback_state(&wbs); + nr_pages = wbs.nr_dirty + wbs.nr_unstable; } return pdflush_operation(background_writeout, nr_pages); } @@ -343,7 +359,7 @@ unsigned long start_jif; unsigned long next_jif; long nr_to_write; - struct page_state ps; + struct writeback_state wbs; struct writeback_control wbc = { .bdi = NULL, .sync_mode = WB_SYNC_NONE, @@ -355,11 +371,11 @@ sync_supers(); - get_page_state(&ps); + get_writeback_state(&wbs); oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100; start_jif = jiffies; next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100; - nr_to_write = ps.nr_dirty + ps.nr_unstable + + nr_to_write = wbs.nr_dirty + wbs.nr_unstable + (inodes_stat.nr_inodes - inodes_stat.nr_unused); while (nr_to_write > 0) { wbc.encountered_congestion = 0; @@ -434,8 +450,8 @@ /* * If ratelimit_pages is too high then we can get into dirty-data overload * if a large number of processes all perform writes at the same time. - * If it is too low then SMP machines will call the (expensive) get_page_state - * too often. + * If it is too low then SMP machines will call the (expensive) + * get_writeback_state too often. * * Here we set ratelimit_pages to a level which ensures that when all CPUs are * dirtying in parallel, we cannot go more than 3% (1/32) over the dirty memory diff -urN linux-2.6.7-rc3/mm/page_alloc.c linux-2.6.7/mm/page_alloc.c --- linux-2.6.7-rc3/mm/page_alloc.c 2004-06-15 23:10:04.555055752 -0700 +++ linux-2.6.7/mm/page_alloc.c 2004-06-15 23:10:52.825087992 -0700 @@ -988,6 +988,23 @@ __get_page_state(ret, sizeof(*ret) / sizeof(unsigned long)); } +unsigned long __read_page_state(unsigned offset) +{ + unsigned long ret = 0; + int cpu; + + for (cpu = 0; cpu < NR_CPUS; cpu++) { + unsigned long in; + + if (!cpu_possible(cpu)) + continue; + + in = (unsigned long)&per_cpu(page_states, cpu) + offset; + ret += *((unsigned long *)in); + } + return ret; +} + void get_zone_counts(unsigned long *active, unsigned long *inactive, unsigned long *free) { diff -urN linux-2.6.7-rc3/mm/vmscan.c linux-2.6.7/mm/vmscan.c --- linux-2.6.7-rc3/mm/vmscan.c 2004-06-15 23:10:04.614058236 -0700 +++ linux-2.6.7/mm/vmscan.c 2004-06-15 23:10:52.855089255 -0700 @@ -240,17 +240,107 @@ unlock_page(page); } +/* possible outcome of pageout() */ +typedef enum { + /* failed to write page out, page is locked */ + PAGE_KEEP, + /* move page to the active list, page is locked */ + PAGE_ACTIVATE, + /* page has been sent to the disk successfully, page is unlocked */ + PAGE_SUCCESS, + /* page is clean and locked */ + PAGE_CLEAN, +} pageout_t; + +/* + * pageout is called by shrink_list() for each dirty page. Calls ->writepage(). + */ +static pageout_t pageout(struct page *page, struct address_space *mapping) +{ + /* + * If the page is dirty, only perform writeback if that write + * will be non-blocking. To prevent this allocation from being + * stalled by pagecache activity. But note that there may be + * stalls if we need to run get_block(). We could test + * PagePrivate for that. + * + * If this process is currently in generic_file_write() against + * this page's queue, we can perform writeback even if that + * will block. + * + * If the page is swapcache, write it back even if that would + * block, for some throttling. This happens by accident, because + * swap_backing_dev_info is bust: it doesn't reflect the + * congestion state of the swapdevs. Easy to fix, if needed. + * See swapfile.c:page_queue_congested(). + */ + if (!is_page_cache_freeable(page)) + return PAGE_KEEP; + if (!mapping) + return PAGE_KEEP; + if (mapping->a_ops->writepage == NULL) + return PAGE_ACTIVATE; + if (!may_write_to_queue(mapping->backing_dev_info)) + return PAGE_KEEP; + + if (clear_page_dirty_for_io(page)) { + int res; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_NONE, + .nr_to_write = SWAP_CLUSTER_MAX, + .nonblocking = 1, + .for_reclaim = 1, + }; + + SetPageReclaim(page); + res = mapping->a_ops->writepage(page, &wbc); + if (res < 0) + handle_write_error(mapping, page, res); + if (res == WRITEPAGE_ACTIVATE) { + ClearPageReclaim(page); + return PAGE_ACTIVATE; + } + if (!PageWriteback(page)) { + /* synchronous write or broken a_ops? */ + ClearPageReclaim(page); + } + + return PAGE_SUCCESS; + } + + return PAGE_CLEAN; +} + +struct scan_control { + /* Ask refill_inactive_zone, or shrink_cache to scan this many pages */ + unsigned long nr_to_scan; + + /* Incremented by the number of inactive pages that were scanned */ + unsigned long nr_scanned; + + /* Incremented by the number of pages reclaimed */ + unsigned long nr_reclaimed; + + unsigned long nr_mapped; /* From page_state */ + + /* Ask shrink_caches, or shrink_zone to scan at this priority */ + unsigned int priority; + + /* This context's GFP mask */ + unsigned int gfp_mask; + + int may_writepage; +}; + /* - * shrink_list returns the number of reclaimed pages + * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed */ -static int -shrink_list(struct list_head *page_list, unsigned int gfp_mask, - int *nr_scanned, int do_writepage) +static int shrink_list(struct list_head *page_list, struct scan_control *sc) { LIST_HEAD(ret_pages); struct pagevec freed_pvec; int pgactivate = 0; - int ret = 0; + int reclaimed = 0; cond_resched(); @@ -267,15 +357,16 @@ if (TestSetPageLocked(page)) goto keep; - /* Double the slab pressure for mapped and swapcache pages */ - if (page_mapped(page) || PageSwapCache(page)) - (*nr_scanned)++; - BUG_ON(PageActive(page)); if (PageWriteback(page)) goto keep_locked; + sc->nr_scanned++; + /* Double the slab pressure for mapped and swapcache pages */ + if (page_mapped(page) || PageSwapCache(page)) + sc->nr_scanned++; + page_map_lock(page); referenced = page_referenced(page); if (referenced && page_mapping_inuse(page)) { @@ -300,8 +391,8 @@ #endif /* CONFIG_SWAP */ mapping = page_mapping(page); - may_enter_fs = (gfp_mask & __GFP_FS) || - (PageSwapCache(page) && (gfp_mask & __GFP_IO)); + may_enter_fs = (sc->gfp_mask & __GFP_FS) || + (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); /* * The page is mapped into the page tables of one or more @@ -321,60 +412,34 @@ } page_map_unlock(page); - /* - * If the page is dirty, only perform writeback if that write - * will be non-blocking. To prevent this allocation from being - * stalled by pagecache activity. But note that there may be - * stalls if we need to run get_block(). We could test - * PagePrivate for that. - * - * If this process is currently in generic_file_write() against - * this page's queue, we can perform writeback even if that - * will block. - * - * If the page is swapcache, write it back even if that would - * block, for some throttling. This happens by accident, because - * swap_backing_dev_info is bust: it doesn't reflect the - * congestion state of the swapdevs. Easy to fix, if needed. - * See swapfile.c:page_queue_congested(). - */ if (PageDirty(page)) { if (referenced) goto keep_locked; - if (!is_page_cache_freeable(page)) - goto keep_locked; - if (!mapping) - goto keep_locked; - if (mapping->a_ops->writepage == NULL) - goto activate_locked; if (!may_enter_fs) goto keep_locked; - if (!may_write_to_queue(mapping->backing_dev_info)) + if (laptop_mode && !sc->may_writepage) goto keep_locked; - if (laptop_mode && !do_writepage) + + /* Page is dirty, try to write it out here */ + switch(pageout(page, mapping)) { + case PAGE_KEEP: goto keep_locked; - if (clear_page_dirty_for_io(page)) { - int res; - struct writeback_control wbc = { - .sync_mode = WB_SYNC_NONE, - .nr_to_write = SWAP_CLUSTER_MAX, - .nonblocking = 1, - .for_reclaim = 1, - }; - - SetPageReclaim(page); - res = mapping->a_ops->writepage(page, &wbc); - if (res < 0) - handle_write_error(mapping, page, res); - if (res == WRITEPAGE_ACTIVATE) { - ClearPageReclaim(page); - goto activate_locked; - } - if (!PageWriteback(page)) { - /* synchronous write or broken a_ops? */ - ClearPageReclaim(page); - } - goto keep; + case PAGE_ACTIVATE: + goto activate_locked; + case PAGE_SUCCESS: + if (PageWriteback(page) || PageDirty(page)) + goto keep; + /* + * A synchronous write - probably a ramdisk. Go + * ahead and try to reclaim the page. + */ + if (TestSetPageLocked(page)) + goto keep; + if (PageDirty(page) || PageWriteback(page)) + goto keep_locked; + mapping = page_mapping(page); + case PAGE_CLEAN: + ; /* try to free the page below */ } } @@ -396,11 +461,11 @@ * the pages which were not successfully invalidated in * truncate_complete_page(). We try to drop those buffers here * and if that worked, and the page is no longer mapped into - * process address space (page_count == 0) it can be freed. + * process address space (page_count == 1) it can be freed. * Otherwise, leave the page on the LRU so it is swappable. */ if (PagePrivate(page)) { - if (!try_to_release_page(page, gfp_mask)) + if (!try_to_release_page(page, sc->gfp_mask)) goto activate_locked; if (!mapping && page_count(page) == 1) goto free_it; @@ -438,7 +503,7 @@ free_it: unlock_page(page); - ret++; + reclaimed++; if (!pagevec_add(&freed_pvec, page)) __pagevec_release_nonlru(&freed_pvec); continue; @@ -456,7 +521,8 @@ if (pagevec_count(&freed_pvec)) __pagevec_release_nonlru(&freed_pvec); mod_page_state(pgactivate, pgactivate); - return ret; + sc->nr_reclaimed += reclaimed; + return reclaimed; } /* @@ -464,19 +530,16 @@ * a batch of pages and working on them outside the lock. Any pages which were * not freed will be added back to the LRU. * - * shrink_cache() is passed the number of pages to scan and returns the number - * of pages which were reclaimed. + * shrink_cache() adds the number of pages reclaimed to sc->nr_reclaimed * * For pagecache intensive workloads, the first loop here is the hottest spot * in the kernel (apart from the copy_*_user functions). */ -static int -shrink_cache(struct zone *zone, unsigned int gfp_mask, - int max_scan, int *total_scanned, int do_writepage) +static void shrink_cache(struct zone *zone, struct scan_control *sc) { LIST_HEAD(page_list); struct pagevec pvec; - int ret = 0; + int max_scan = sc->nr_to_scan; pagevec_init(&pvec, 1); @@ -522,17 +585,11 @@ mod_page_state_zone(zone, pgscan_kswapd, nr_scan); else mod_page_state_zone(zone, pgscan_direct, nr_scan); - nr_freed = shrink_list(&page_list, gfp_mask, - total_scanned, do_writepage); - *total_scanned += nr_taken; + nr_freed = shrink_list(&page_list, sc); if (current_is_kswapd()) mod_page_state(kswapd_steal, nr_freed); mod_page_state_zone(zone, pgsteal, nr_freed); - ret += nr_freed; - if (nr_freed <= 0 && list_empty(&page_list)) - goto done; - spin_lock_irq(&zone->lru_lock); /* * Put back any unfreeable pages. @@ -556,7 +613,6 @@ spin_unlock_irq(&zone->lru_lock); done: pagevec_release(&pvec); - return ret; } /* @@ -577,12 +633,12 @@ * But we had to alter page->flags anyway. */ static void -refill_inactive_zone(struct zone *zone, const int nr_pages_in, - struct page_state *ps) +refill_inactive_zone(struct zone *zone, struct scan_control *sc) { int pgmoved; int pgdeactivate = 0; - int nr_pages = nr_pages_in; + int pgscanned = 0; + int nr_pages = sc->nr_to_scan; LIST_HEAD(l_hold); /* The pages which were snipped off */ LIST_HEAD(l_inactive); /* Pages to go onto the inactive_list */ LIST_HEAD(l_active); /* Pages to go onto the active_list */ @@ -596,7 +652,7 @@ lru_add_drain(); pgmoved = 0; spin_lock_irq(&zone->lru_lock); - while (nr_pages && !list_empty(&zone->active_list)) { + while (pgscanned < nr_pages && !list_empty(&zone->active_list)) { page = lru_to_page(&zone->active_list); prefetchw_prev_lru_page(page, &zone->active_list, flags); if (!TestClearPageLRU(page)) @@ -616,7 +672,7 @@ list_add(&page->lru, &l_hold); pgmoved++; } - nr_pages--; + pgscanned++; } zone->nr_active -= pgmoved; spin_unlock_irq(&zone->lru_lock); @@ -632,7 +688,7 @@ * mapped memory instead of just pagecache. Work out how much memory * is mapped. */ - mapped_ratio = (ps->nr_mapped * 100) / total_memory; + mapped_ratio = (sc->nr_mapped * 100) / total_memory; /* * Now decide how much we really want to unmap some pages. The mapped @@ -731,7 +787,7 @@ spin_unlock_irq(&zone->lru_lock); pagevec_release(&pvec); - mod_page_state_zone(zone, pgrefill, nr_pages_in - nr_pages); + mod_page_state_zone(zone, pgrefill, pgscanned); mod_page_state(pgdeactivate, pgdeactivate); } @@ -739,13 +795,14 @@ * Scan `nr_pages' from this zone. Returns the number of reclaimed pages. * This is a basic per-zone page freer. Used by both kswapd and direct reclaim. */ -static int -shrink_zone(struct zone *zone, int max_scan, unsigned int gfp_mask, - int *total_scanned, struct page_state *ps, int do_writepage) +static void +shrink_zone(struct zone *zone, struct scan_control *sc) { - unsigned long scan_active; + unsigned long scan_active, scan_inactive; int count; + scan_inactive = (zone->nr_active + zone->nr_inactive) >> sc->priority; + /* * Try to keep the active list 2/3 of the size of the cache. And * make sure that refill_inactive is given a decent number of pages. @@ -758,13 +815,13 @@ */ if (zone->nr_active >= 4*(zone->nr_inactive*2 + 1)) { /* Don't scan more than 4 times the inactive list scan size */ - scan_active = 4*max_scan; + scan_active = 4*scan_inactive; } else { unsigned long long tmp; /* Cast to long long so the multiply doesn't overflow */ - tmp = (unsigned long long)max_scan * zone->nr_active; + tmp = (unsigned long long)scan_inactive * zone->nr_active; do_div(tmp, zone->nr_inactive*2 + 1); scan_active = (unsigned long)tmp; } @@ -773,17 +830,17 @@ count = atomic_read(&zone->nr_scan_active); if (count >= SWAP_CLUSTER_MAX) { atomic_set(&zone->nr_scan_active, 0); - refill_inactive_zone(zone, count, ps); + sc->nr_to_scan = count; + refill_inactive_zone(zone, sc); } - atomic_add(max_scan, &zone->nr_scan_inactive); + atomic_add(scan_inactive, &zone->nr_scan_inactive); count = atomic_read(&zone->nr_scan_inactive); if (count >= SWAP_CLUSTER_MAX) { atomic_set(&zone->nr_scan_inactive, 0); - return shrink_cache(zone, gfp_mask, count, - total_scanned, do_writepage); + sc->nr_to_scan = count; + shrink_cache(zone, sc); } - return 0; } /* @@ -802,29 +859,23 @@ * If a zone is deemed to be full of pinned pages then just give it a light * scan then give up on it. */ -static int -shrink_caches(struct zone **zones, int priority, int *total_scanned, - int gfp_mask, struct page_state *ps, int do_writepage) +static void +shrink_caches(struct zone **zones, struct scan_control *sc) { - int ret = 0; int i; for (i = 0; zones[i] != NULL; i++) { struct zone *zone = zones[i]; - int max_scan; - zone->temp_priority = priority; - if (zone->prev_priority > priority) - zone->prev_priority = priority; + zone->temp_priority = sc->priority; + if (zone->prev_priority > sc->priority) + zone->prev_priority = sc->priority; - if (zone->all_unreclaimable && priority != DEF_PRIORITY) + if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY) continue; /* Let kswapd poll it */ - max_scan = (zone->nr_active + zone->nr_inactive) >> priority; - ret += shrink_zone(zone, max_scan, gfp_mask, - total_scanned, ps, do_writepage); + shrink_zone(zone, sc); } - return ret; } /* @@ -835,25 +886,23 @@ * * If the caller is !__GFP_FS then the probability of a failure is reasonably * high - the zone may be full of dirty or under-writeback pages, which this - * caller can't do much about. So for !__GFP_FS callers, we just perform a - * small LRU walk and if that didn't work out, fail the allocation back to the - * caller. GFP_NOFS allocators need to know how to deal with it. Kicking - * bdflush, waiting and retrying will work. - * - * This is a fairly lame algorithm - it can result in excessive CPU burning and - * excessive rotation of the inactive list, which is _supposed_ to be an LRU, - * yes? + * caller can't do much about. We kick pdflush and take explicit naps in the + * hope that some of these pages can be written. But if the allocating task + * holds filesystem locks which prevent writeout this might not work, and the + * allocation attempt will fail. */ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask, unsigned int order) { int priority; int ret = 0; - int nr_reclaimed = 0; + int total_scanned = 0, total_reclaimed = 0; struct reclaim_state *reclaim_state = current->reclaim_state; + struct scan_control sc; int i; - unsigned long total_scanned = 0; - int do_writepage = 0; + + sc.gfp_mask = gfp_mask; + sc.may_writepage = 0; inc_page_state(allocstall); @@ -861,23 +910,23 @@ zones[i]->temp_priority = DEF_PRIORITY; for (priority = DEF_PRIORITY; priority >= 0; priority--) { - int scanned = 0; - struct page_state ps; - - get_page_state(&ps); - nr_reclaimed += shrink_caches(zones, priority, &scanned, - gfp_mask, &ps, do_writepage); - shrink_slab(scanned, gfp_mask); + sc.nr_mapped = read_page_state(nr_mapped); + sc.nr_scanned = 0; + sc.nr_reclaimed = 0; + sc.priority = priority; + shrink_caches(zones, &sc); + shrink_slab(sc.nr_scanned, gfp_mask); if (reclaim_state) { - nr_reclaimed += reclaim_state->reclaimed_slab; + sc.nr_reclaimed += reclaim_state->reclaimed_slab; reclaim_state->reclaimed_slab = 0; } - if (nr_reclaimed >= SWAP_CLUSTER_MAX) { + if (sc.nr_reclaimed >= SWAP_CLUSTER_MAX) { ret = 1; goto out; } - if (!(gfp_mask & __GFP_FS)) - break; /* Let the caller handle it */ + total_scanned += sc.nr_scanned; + total_reclaimed += sc.nr_reclaimed; + /* * Try to write back as many pages as we just scanned. This * tends to cause slow streaming writers to write data to the @@ -885,14 +934,13 @@ * that's undesirable in laptop mode, where we *want* lumpy * writeout. So in laptop mode, write out the whole world. */ - total_scanned += scanned; if (total_scanned > SWAP_CLUSTER_MAX + SWAP_CLUSTER_MAX/2) { wakeup_bdflush(laptop_mode ? 0 : total_scanned); - do_writepage = 1; + sc.may_writepage = 1; } /* Take a nap, wait for some writeback to complete */ - if (scanned && priority < DEF_PRIORITY - 2) + if (sc.nr_scanned && priority < DEF_PRIORITY - 2) blk_congestion_wait(WRITE, HZ/10); } if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) @@ -928,15 +976,18 @@ * the page allocator fallback scheme to ensure that aging of pages is balanced * across the zones. */ -static int balance_pgdat(pg_data_t *pgdat, int nr_pages, struct page_state *ps) +static int balance_pgdat(pg_data_t *pgdat, int nr_pages) { int to_free = nr_pages; int priority; int i; + int total_scanned = 0, total_reclaimed = 0; struct reclaim_state *reclaim_state = current->reclaim_state; - unsigned long total_scanned = 0; - unsigned long total_reclaimed = 0; - int do_writepage = 0; + struct scan_control sc; + + sc.gfp_mask = GFP_KERNEL; + sc.may_writepage = 0; + sc.nr_mapped = read_page_state(nr_mapped); inc_page_state(pageoutrun); @@ -984,9 +1035,6 @@ */ for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; - int max_scan; - int reclaimed; - int scanned = 0; if (zone->all_unreclaimable && priority != DEF_PRIORITY) continue; @@ -998,16 +1046,14 @@ zone->temp_priority = priority; if (zone->prev_priority > priority) zone->prev_priority = priority; - max_scan = (zone->nr_active + zone->nr_inactive) - >> priority; - reclaimed = shrink_zone(zone, max_scan, GFP_KERNEL, - &scanned, ps, do_writepage); - total_scanned += scanned; + sc.nr_scanned = 0; + sc.nr_reclaimed = 0; + sc.priority = priority; + shrink_zone(zone, &sc); reclaim_state->reclaimed_slab = 0; - shrink_slab(scanned, GFP_KERNEL); - reclaimed += reclaim_state->reclaimed_slab; - total_reclaimed += reclaimed; - to_free -= reclaimed; + shrink_slab(sc.nr_scanned, GFP_KERNEL); + sc.nr_reclaimed += reclaim_state->reclaimed_slab; + total_reclaimed += sc.nr_reclaimed; if (zone->all_unreclaimable) continue; if (zone->pages_scanned > zone->present_pages * 2) @@ -1019,9 +1065,9 @@ */ if (total_scanned > SWAP_CLUSTER_MAX * 2 && total_scanned > total_reclaimed+total_reclaimed/2) - do_writepage = 1; + sc.may_writepage = 1; } - if (nr_pages && to_free > 0) + if (nr_pages && to_free > total_reclaimed) continue; /* swsusp: need to do more work */ if (all_zones_ok) break; /* kswapd: all done */ @@ -1085,15 +1131,13 @@ tsk->flags |= PF_MEMALLOC|PF_KSWAPD; for ( ; ; ) { - struct page_state ps; - if (current->flags & PF_FREEZE) refrigerator(PF_FREEZE); prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE); schedule(); finish_wait(&pgdat->kswapd_wait, &wait); - get_page_state(&ps); - balance_pgdat(pgdat, 0, &ps); + + balance_pgdat(pgdat, 0); } } @@ -1126,10 +1170,7 @@ current->reclaim_state = &reclaim_state; for_each_pgdat(pgdat) { int freed; - struct page_state ps; - - get_page_state(&ps); - freed = balance_pgdat(pgdat, nr_to_free, &ps); + freed = balance_pgdat(pgdat, nr_to_free); ret += freed; nr_to_free -= freed; if (nr_to_free <= 0) diff -urN linux-2.6.7-rc3/net/bluetooth/l2cap.c linux-2.6.7/net/bluetooth/l2cap.c --- linux-2.6.7-rc3/net/bluetooth/l2cap.c 2004-06-15 23:10:05.533096920 -0700 +++ linux-2.6.7/net/bluetooth/l2cap.c 2004-06-15 23:10:53.354110270 -0700 @@ -95,17 +95,13 @@ static void l2cap_sock_set_timer(struct sock *sk, long timeout) { BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); - - if (!mod_timer(&sk->sk_timer, jiffies + timeout)) - sock_hold(sk); + sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); } static void l2cap_sock_clear_timer(struct sock *sk) { BT_DBG("sock %p state %d", sk, sk->sk_state); - - if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer)) - __sock_put(sk); + sk_stop_timer(sk, &sk->sk_timer); } static void l2cap_sock_init_timer(struct sock *sk) diff -urN linux-2.6.7-rc3/net/bluetooth/sco.c linux-2.6.7/net/bluetooth/sco.c --- linux-2.6.7-rc3/net/bluetooth/sco.c 2004-06-15 23:10:05.635101213 -0700 +++ linux-2.6.7/net/bluetooth/sco.c 2004-06-15 23:10:53.383111491 -0700 @@ -91,17 +91,13 @@ static void sco_sock_set_timer(struct sock *sk, long timeout) { BT_DBG("sock %p state %d timeout %ld", sk, sk->sk_state, timeout); - - if (!mod_timer(&sk->sk_timer, jiffies + timeout)) - sock_hold(sk); + sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); } static void sco_sock_clear_timer(struct sock *sk) { BT_DBG("sock %p state %d", sk, sk->sk_state); - - if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer)) - __sock_put(sk); + sk_stop_timer(sk, &sk->sk_timer); } static void sco_sock_init_timer(struct sock *sk) diff -urN linux-2.6.7-rc3/net/core/dst.c linux-2.6.7/net/core/dst.c --- linux-2.6.7-rc3/net/core/dst.c 2004-06-15 23:10:05.917113084 -0700 +++ linux-2.6.7/net/core/dst.c 2004-06-15 23:10:53.821129937 -0700 @@ -230,8 +230,8 @@ if (event!=NETDEV_DOWN && dst->output == dst_discard_out) { dst->dev = &loopback_dev; - dev_put(dev); dev_hold(&loopback_dev); + dev_put(dev); dst->output = dst_discard_out; if (dst->neighbour && dst->neighbour->dev == dev) { dst->neighbour->dev = &loopback_dev; @@ -242,6 +242,8 @@ dst->input = dst_discard_in; dst->output = dst_discard_out; } + if (dst->ops->ifdown) + dst->ops->ifdown(dst, event != NETDEV_DOWN); } } spin_unlock_bh(&dst_lock); diff -urN linux-2.6.7-rc3/net/core/ethtool.c linux-2.6.7/net/core/ethtool.c --- linux-2.6.7-rc3/net/core/ethtool.c 2004-06-15 23:10:05.955114683 -0700 +++ linux-2.6.7/net/core/ethtool.c 2004-06-15 23:10:53.827130189 -0700 @@ -652,6 +652,7 @@ struct net_device *dev = __dev_get_by_name(ifr->ifr_name); void __user *useraddr = ifr->ifr_data; u32 ethcmd; + int rc; /* * XXX: This can be pushed down into the ethtool_* handlers that @@ -669,70 +670,109 @@ if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) return -EFAULT; + if(dev->ethtool_ops->begin) + if ((rc = dev->ethtool_ops->begin(dev)) < 0) + return rc; + switch (ethcmd) { case ETHTOOL_GSET: - return ethtool_get_settings(dev, useraddr); + rc = ethtool_get_settings(dev, useraddr); + break; case ETHTOOL_SSET: - return ethtool_set_settings(dev, useraddr); + rc = ethtool_set_settings(dev, useraddr); + break; case ETHTOOL_GDRVINFO: - return ethtool_get_drvinfo(dev, useraddr); + rc = ethtool_get_drvinfo(dev, useraddr); + + break; case ETHTOOL_GREGS: - return ethtool_get_regs(dev, useraddr); + rc = ethtool_get_regs(dev, useraddr); + break; case ETHTOOL_GWOL: - return ethtool_get_wol(dev, useraddr); + rc = ethtool_get_wol(dev, useraddr); + break; case ETHTOOL_SWOL: - return ethtool_set_wol(dev, useraddr); + rc = ethtool_set_wol(dev, useraddr); + break; case ETHTOOL_GMSGLVL: - return ethtool_get_msglevel(dev, useraddr); + rc = ethtool_get_msglevel(dev, useraddr); + break; case ETHTOOL_SMSGLVL: - return ethtool_set_msglevel(dev, useraddr); + rc = ethtool_set_msglevel(dev, useraddr); + break; case ETHTOOL_NWAY_RST: - return ethtool_nway_reset(dev); + rc = ethtool_nway_reset(dev); + break; case ETHTOOL_GLINK: - return ethtool_get_link(dev, useraddr); + rc = ethtool_get_link(dev, useraddr); + break; case ETHTOOL_GEEPROM: - return ethtool_get_eeprom(dev, useraddr); + rc = ethtool_get_eeprom(dev, useraddr); + break; case ETHTOOL_SEEPROM: - return ethtool_set_eeprom(dev, useraddr); + rc = ethtool_set_eeprom(dev, useraddr); + break; case ETHTOOL_GCOALESCE: - return ethtool_get_coalesce(dev, useraddr); + rc = ethtool_get_coalesce(dev, useraddr); + break; case ETHTOOL_SCOALESCE: - return ethtool_set_coalesce(dev, useraddr); + rc = ethtool_set_coalesce(dev, useraddr); + break; case ETHTOOL_GRINGPARAM: - return ethtool_get_ringparam(dev, useraddr); + rc = ethtool_get_ringparam(dev, useraddr); + break; case ETHTOOL_SRINGPARAM: - return ethtool_set_ringparam(dev, useraddr); + rc = ethtool_set_ringparam(dev, useraddr); + break; case ETHTOOL_GPAUSEPARAM: - return ethtool_get_pauseparam(dev, useraddr); + rc = ethtool_get_pauseparam(dev, useraddr); + break; case ETHTOOL_SPAUSEPARAM: - return ethtool_set_pauseparam(dev, useraddr); + rc = ethtool_set_pauseparam(dev, useraddr); + break; case ETHTOOL_GRXCSUM: - return ethtool_get_rx_csum(dev, useraddr); + rc = ethtool_get_rx_csum(dev, useraddr); + break; case ETHTOOL_SRXCSUM: - return ethtool_set_rx_csum(dev, useraddr); + rc = ethtool_set_rx_csum(dev, useraddr); + break; case ETHTOOL_GTXCSUM: - return ethtool_get_tx_csum(dev, useraddr); + rc = ethtool_get_tx_csum(dev, useraddr); + break; case ETHTOOL_STXCSUM: - return ethtool_set_tx_csum(dev, useraddr); + rc = ethtool_set_tx_csum(dev, useraddr); + break; case ETHTOOL_GSG: - return ethtool_get_sg(dev, useraddr); + rc = ethtool_get_sg(dev, useraddr); + break; case ETHTOOL_SSG: - return ethtool_set_sg(dev, useraddr); + rc = ethtool_set_sg(dev, useraddr); + break; case ETHTOOL_GTSO: - return ethtool_get_tso(dev, useraddr); + rc = ethtool_get_tso(dev, useraddr); + break; case ETHTOOL_STSO: - return ethtool_set_tso(dev, useraddr); + rc = ethtool_set_tso(dev, useraddr); + break; case ETHTOOL_TEST: - return ethtool_self_test(dev, useraddr); + rc = ethtool_self_test(dev, useraddr); + break; case ETHTOOL_GSTRINGS: - return ethtool_get_strings(dev, useraddr); + rc = ethtool_get_strings(dev, useraddr); + break; case ETHTOOL_PHYS_ID: - return ethtool_phys_id(dev, useraddr); + rc = ethtool_phys_id(dev, useraddr); + break; case ETHTOOL_GSTATS: - return ethtool_get_stats(dev, useraddr); + rc = ethtool_get_stats(dev, useraddr); + break; default: - return -EOPNOTSUPP; + rc = -EOPNOTSUPP; } + + if(dev->ethtool_ops->complete) + dev->ethtool_ops->complete(dev); + return rc; ioctl: if (dev->do_ioctl) diff -urN linux-2.6.7-rc3/net/core/sock.c linux-2.6.7/net/core/sock.c --- linux-2.6.7-rc3/net/core/sock.c 2004-06-15 23:10:06.130122050 -0700 +++ linux-2.6.7/net/core/sock.c 2004-06-15 23:10:53.875132211 -0700 @@ -917,6 +917,31 @@ } while((skb = sk->sk_backlog.head) != NULL); } +/** + * sk_wait_data - wait for data to arrive at sk_receive_queue + * sk - sock to wait on + * timeo - for how long + * + * Now socket state including sk->sk_err is changed only under lock, + * hence we may omit checks after joining wait queue. + * We check receive queue before schedule() only as optimization; + * it is very likely that release_sock() added new data. + */ +int sk_wait_data(struct sock *sk, long *timeo) +{ + int rc; + DEFINE_WAIT(wait); + + prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + rc = sk_wait_event(sk, timeo, !skb_queue_empty(&sk->sk_receive_queue)); + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + finish_wait(sk->sk_sleep, &wait); + return rc; +} + +EXPORT_SYMBOL(sk_wait_data); + /* * Set of default routines for initialising struct proto_ops when * the protocol does not support a particular function. In certain @@ -1099,6 +1124,23 @@ sk_wake_async(sk, 3, POLL_PRI); } +void sk_reset_timer(struct sock *sk, struct timer_list* timer, + unsigned long expires) +{ + if (!mod_timer(timer, expires)) + sock_hold(sk); +} + +EXPORT_SYMBOL(sk_reset_timer); + +void sk_stop_timer(struct sock *sk, struct timer_list* timer) +{ + if (timer_pending(timer) && del_timer(timer)) + __sock_put(sk); +} + +EXPORT_SYMBOL(sk_stop_timer); + void sock_init_data(struct socket *sock, struct sock *sk) { skb_queue_head_init(&sk->sk_receive_queue); diff -urN linux-2.6.7-rc3/net/ipv4/netfilter/arp_tables.c linux-2.6.7/net/ipv4/netfilter/arp_tables.c --- linux-2.6.7-rc3/net/ipv4/netfilter/arp_tables.c 2004-06-15 23:10:07.468178372 -0700 +++ linux-2.6.7/net/ipv4/netfilter/arp_tables.c 2004-06-15 23:10:54.489158068 -0700 @@ -56,6 +56,7 @@ #endif #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) +static DECLARE_MUTEX(arpt_mutex); #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) @@ -178,11 +179,10 @@ return 0; } - /* Look for ifname matches; this should unroll nicely. */ - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { - ret |= (((const unsigned long *)indev)[i] - ^ ((const unsigned long *)arpinfo->iniface)[i]) - & ((const unsigned long *)arpinfo->iniface_mask)[i]; + /* Look for ifname matches. */ + for (i = 0, ret = 0; i < IFNAMSIZ; i++) { + ret |= (indev[i] ^ arpinfo->iniface[i]) + & arpinfo->iniface_mask[i]; } if (FWINV(ret != 0, ARPT_INV_VIA_IN)) { diff -urN linux-2.6.7-rc3/net/ipv4/netfilter/ip_conntrack_core.c linux-2.6.7/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.6.7-rc3/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-15 23:10:07.552181908 -0700 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_core.c 2004-06-15 23:10:54.516159205 -0700 @@ -324,8 +324,9 @@ ip_conntrack_destroyed(ct); WRITE_LOCK(&ip_conntrack_lock); - /* Delete us from our own list to prevent corruption later */ - list_del(&ct->sibling_list); + /* Make sure don't leave any orphaned expectations lying around */ + if (ct->expecting) + remove_expectations(ct, 1); /* Delete our master expectation */ if (ct->master) { @@ -1127,10 +1128,8 @@ DUMP_TUPLE(newreply); conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; - if (!conntrack->master) - conntrack->helper = LIST_FIND(&helpers, helper_cmp, - struct ip_conntrack_helper *, - newreply); + if (!conntrack->master && list_empty(&conntrack->sibling_list)) + conntrack->helper = ip_ct_find_helper(newreply); WRITE_UNLOCK(&ip_conntrack_lock); return 1; diff -urN linux-2.6.7-rc3/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.6.7/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- linux-2.6.7-rc3/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-09 19:33:21.000000000 -0700 +++ linux-2.6.7/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-06-15 23:10:54.551160679 -0700 @@ -177,6 +177,8 @@ if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &tcph, sizeof(tcph)) != 0) return -1; + if (skb->len < skb->nh.iph->ihl * 4 + tcph.doff * 4) + return -1; /* If only reply is a RST, we can consider ourselves not to have an established connection: this is a fairly common diff -urN linux-2.6.7-rc3/net/ipv4/route.c linux-2.6.7/net/ipv4/route.c --- linux-2.6.7-rc3/net/ipv4/route.c 2004-06-15 23:10:07.724189148 -0700 +++ linux-2.6.7/net/ipv4/route.c 2004-06-15 23:10:54.627163880 -0700 @@ -138,6 +138,7 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); static void ipv4_dst_destroy(struct dst_entry *dst); +static void ipv4_dst_ifdown(struct dst_entry *dst, int how); static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); static void ipv4_link_failure(struct sk_buff *skb); static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); @@ -150,6 +151,7 @@ .gc = rt_garbage_collect, .check = ipv4_dst_check, .destroy = ipv4_dst_destroy, + .ifdown = ipv4_dst_ifdown, .negative_advice = ipv4_negative_advice, .link_failure = ipv4_link_failure, .update_pmtu = ip_rt_update_pmtu, @@ -1336,6 +1338,16 @@ } } +static void ipv4_dst_ifdown(struct dst_entry *dst, int how) +{ + struct rtable *rt = (struct rtable *) dst; + struct in_device *idev = rt->idev; + if (idev) { + rt->idev = NULL; + in_dev_put(idev); + } +} + static void ipv4_link_failure(struct sk_buff *skb) { struct rtable *rt; diff -urN linux-2.6.7-rc3/net/ipv4/tcp.c linux-2.6.7/net/ipv4/tcp.c --- linux-2.6.7-rc3/net/ipv4/tcp.c 2004-06-15 23:10:07.753190369 -0700 +++ linux-2.6.7/net/ipv4/tcp.c 2004-06-15 23:10:54.664165438 -0700 @@ -648,7 +648,7 @@ local_bh_enable(); sock_put(child); - tcp_acceptq_removed(sk); + sk_acceptq_removed(sk); tcp_openreq_fastfree(req); } BUG_TRAP(!sk->sk_ack_backlog); @@ -1296,18 +1296,6 @@ return -EAGAIN; } -/* - * Release a skb if it is no longer needed. This routine - * must be called with interrupts disabled or with the - * socket locked so that the sk_buff queue operation is ok. - */ - -static inline void tcp_eat_skb(struct sock *sk, struct sk_buff *skb) -{ - __skb_unlink(skb, &sk->sk_receive_queue); - __kfree_skb(skb); -} - /* Clean up the receive buffer for full frames taken by the user, * then send an ACK if necessary. COPIED is the number of bytes * tcp_recvmsg has given to the user so far, it speeds up the @@ -1368,31 +1356,6 @@ tcp_send_ack(sk); } -/* Now socket state including sk->sk_err is changed only under lock, - * hence we may omit checks after joining wait queue. - * We check receive queue before schedule() only as optimization; - * it is very likely that release_sock() added new data. - */ - -static long tcp_data_wait(struct sock *sk, long timeo) -{ - DEFINE_WAIT(wait); - - prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); - - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - release_sock(sk); - - if (skb_queue_empty(&sk->sk_receive_queue)) - timeo = schedule_timeout(timeo); - - lock_sock(sk); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - - finish_wait(sk->sk_sleep, &wait); - return timeo; -} - static void tcp_prequeue_process(struct sock *sk) { struct sk_buff *skb; @@ -1473,11 +1436,11 @@ break; } if (skb->h.th->fin) { - tcp_eat_skb(sk, skb); + sk_eat_skb(sk, skb); ++seq; break; } - tcp_eat_skb(sk, skb); + sk_eat_skb(sk, skb); if (!desc->count) break; } @@ -1672,9 +1635,8 @@ /* Do not sleep, just process backlog. */ release_sock(sk); lock_sock(sk); - } else { - timeo = tcp_data_wait(sk, timeo); - } + } else + sk_wait_data(sk, &timeo); if (user_recv) { int chunk; @@ -1758,14 +1720,14 @@ if (skb->h.th->fin) goto found_fin_ok; if (!(flags & MSG_PEEK)) - tcp_eat_skb(sk, skb); + sk_eat_skb(sk, skb); continue; found_fin_ok: /* Process the FIN. */ ++*seq; if (!(flags & MSG_PEEK)) - tcp_eat_skb(sk, skb); + sk_eat_skb(sk, skb); break; } while (len > 0); @@ -2263,7 +2225,7 @@ tp->accept_queue_tail = NULL; newsk = req->sk; - tcp_acceptq_removed(sk); + sk_acceptq_removed(sk); tcp_openreq_fastfree(req); BUG_TRAP(newsk->sk_state != TCP_SYN_RECV); release_sock(sk); diff -urN linux-2.6.7-rc3/net/ipv4/tcp_diag.c linux-2.6.7/net/ipv4/tcp_diag.c --- linux-2.6.7-rc3/net/ipv4/tcp_diag.c 2004-06-15 23:10:07.754190411 -0700 +++ linux-2.6.7/net/ipv4/tcp_diag.c 2004-06-15 23:10:54.674165859 -0700 @@ -91,6 +91,9 @@ info->tcpi_snd_cwnd = tp->snd_cwnd; info->tcpi_advmss = tp->advmss; info->tcpi_reordering = tp->reordering; + + info->tcpi_rcv_rtt = ((1000000*tp->rcv_rtt_est.rtt)/HZ)>>3; + info->tcpi_rcv_space = tp->rcvq_space.space; } static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk, diff -urN linux-2.6.7-rc3/net/ipv4/tcp_input.c linux-2.6.7/net/ipv4/tcp_input.c --- linux-2.6.7-rc3/net/ipv4/tcp_input.c 2004-06-15 23:10:07.777191379 -0700 +++ linux-2.6.7/net/ipv4/tcp_input.c 2004-06-15 23:10:54.717167670 -0700 @@ -463,6 +463,8 @@ tp->rcvq_space.space = space; if (sysctl_tcp_moderate_rcvbuf) { + int new_clamp = space; + /* Receive space grows, normalize in order to * take into account packet headers and sk_buff * structure overhead. @@ -472,10 +474,16 @@ space = 1; rcvmem = (tp->advmss + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff)); + while (tcp_win_from_space(rcvmem) < tp->advmss) + rcvmem += 128; space *= rcvmem; space = min(space, sysctl_tcp_rmem[2]); - if (space > sk->sk_rcvbuf) + if (space > sk->sk_rcvbuf) { sk->sk_rcvbuf = space; + + /* Make the window clamp follow along. */ + tp->window_clamp = new_clamp; + } } } diff -urN linux-2.6.7-rc3/net/ipv4/tcp_ipv4.c linux-2.6.7/net/ipv4/tcp_ipv4.c --- linux-2.6.7-rc3/net/ipv4/tcp_ipv4.c 2004-06-15 23:10:07.780191506 -0700 +++ linux-2.6.7/net/ipv4/tcp_ipv4.c 2004-06-15 23:10:54.719167754 -0700 @@ -1442,7 +1442,7 @@ * clogging syn queue with openreqs with exponentially increasing * timeout. */ - if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) + if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) goto drop; req = tcp_openreq_alloc(); @@ -1567,7 +1567,7 @@ struct tcp_opt *newtp; struct sock *newsk; - if (tcp_acceptq_is_full(sk)) + if (sk_acceptq_is_full(sk)) goto exit_overflow; if (!dst && (dst = tcp_v4_route_req(sk, req)) == NULL) diff -urN linux-2.6.7-rc3/net/ipv4/tcp_output.c linux-2.6.7/net/ipv4/tcp_output.c --- linux-2.6.7-rc3/net/ipv4/tcp_output.c 2004-05-09 19:32:53.000000000 -0700 +++ linux-2.6.7/net/ipv4/tcp_output.c 2004-06-15 23:10:54.721167839 -0700 @@ -1389,8 +1389,7 @@ } tp->ack.pending |= TCP_ACK_SCHED|TCP_ACK_TIMER; tp->ack.timeout = timeout; - if (!mod_timer(&tp->delack_timer, timeout)) - sock_hold(sk); + sk_reset_timer(sk, &tp->delack_timer, timeout); } /* This routine sends an ack and also updates the window. */ diff -urN linux-2.6.7-rc3/net/ipv4/tcp_timer.c linux-2.6.7/net/ipv4/tcp_timer.c --- linux-2.6.7-rc3/net/ipv4/tcp_timer.c 2004-05-09 19:33:20.000000000 -0700 +++ linux-2.6.7/net/ipv4/tcp_timer.c 2004-06-15 23:10:54.722167881 -0700 @@ -68,18 +68,13 @@ struct tcp_opt *tp = tcp_sk(sk); tp->pending = 0; - if (timer_pending(&tp->retransmit_timer) && - del_timer(&tp->retransmit_timer)) - __sock_put(sk); + sk_stop_timer(sk, &tp->retransmit_timer); tp->ack.pending = 0; tp->ack.blocked = 0; - if (timer_pending(&tp->delack_timer) && - del_timer(&tp->delack_timer)) - __sock_put(sk); + sk_stop_timer(sk, &tp->delack_timer); - if (timer_pending(&sk->sk_timer) && del_timer(&sk->sk_timer)) - __sock_put(sk); + sk_stop_timer(sk, &sk->sk_timer); } static void tcp_write_err(struct sock *sk) @@ -218,8 +213,7 @@ /* Try again later. */ tp->ack.blocked = 1; NET_INC_STATS_BH(DelayedACKLocked); - if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN)) - sock_hold(sk); + sk_reset_timer(sk, &tp->delack_timer, jiffies + TCP_DELACK_MIN); goto out_unlock; } @@ -229,8 +223,7 @@ goto out; if (time_after(tp->ack.timeout, jiffies)) { - if (!mod_timer(&tp->delack_timer, tp->ack.timeout)) - sock_hold(sk); + sk_reset_timer(sk, &tp->delack_timer, tp->ack.timeout); goto out; } tp->ack.pending &= ~TCP_ACK_TIMER; @@ -429,8 +422,7 @@ bh_lock_sock(sk); if (sock_owned_by_user(sk)) { /* Try again later */ - if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20))) - sock_hold(sk); + sk_reset_timer(sk, &tp->retransmit_timer, jiffies + (HZ / 20)); goto out_unlock; } @@ -438,8 +430,7 @@ goto out; if (time_after(tp->timeout, jiffies)) { - if (!mod_timer(&tp->retransmit_timer, tp->timeout)) - sock_hold(sk); + sk_reset_timer(sk, &tp->retransmit_timer, tp->timeout); goto out; } @@ -557,14 +548,12 @@ void tcp_delete_keepalive_timer (struct sock *sk) { - if (timer_pending(&sk->sk_timer) && del_timer (&sk->sk_timer)) - __sock_put(sk); + sk_stop_timer(sk, &sk->sk_timer); } void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len) { - if (!mod_timer(&sk->sk_timer, jiffies + len)) - sock_hold(sk); + sk_reset_timer(sk, &sk->sk_timer, jiffies + len); } void tcp_set_keepalive(struct sock *sk, int val) diff -urN linux-2.6.7-rc3/net/ipv6/ah6.c linux-2.6.7/net/ipv6/ah6.c --- linux-2.6.7-rc3/net/ipv6/ah6.c 2004-06-15 23:10:07.959199040 -0700 +++ linux-2.6.7/net/ipv6/ah6.c 2004-06-15 23:10:54.803171292 -0700 @@ -363,7 +363,7 @@ struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); struct xfrm_state *x; - if (type != ICMPV6_DEST_UNREACH || + if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) return; diff -urN linux-2.6.7-rc3/net/ipv6/datagram.c linux-2.6.7/net/ipv6/datagram.c --- linux-2.6.7-rc3/net/ipv6/datagram.c 2004-05-09 19:32:00.000000000 -0700 +++ linux-2.6.7/net/ipv6/datagram.c 2004-06-15 23:10:54.840172850 -0700 @@ -145,10 +145,8 @@ (struct in6_addr *)(skb->nh.raw + serr->addr_offset)); if (np->sndflow) sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK; - if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) { - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; - sin->sin6_scope_id = opt->iif; - } + if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin->sin6_scope_id = IP6CB(skb)->iif; } else { ipv6_addr_set(&sin->sin6_addr, 0, 0, htonl(0xffff), @@ -167,10 +165,8 @@ ipv6_addr_copy(&sin->sin6_addr, &skb->nh.ipv6h->saddr); if (np->rxopt.all) datagram_recv_ctl(sk, msg, skb); - if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) { - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; - sin->sin6_scope_id = opt->iif; - } + if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin->sin6_scope_id = IP6CB(skb)->iif; } else { struct inet_opt *inet = inet_sk(sk); @@ -211,7 +207,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) { struct ipv6_pinfo *np = inet6_sk(sk); - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); if (np->rxopt.bits.rxinfo) { struct in6_pktinfo src_info; diff -urN linux-2.6.7-rc3/net/ipv6/esp6.c linux-2.6.7/net/ipv6/esp6.c --- linux-2.6.7-rc3/net/ipv6/esp6.c 2004-06-15 23:10:08.019201566 -0700 +++ linux-2.6.7/net/ipv6/esp6.c 2004-06-15 23:10:54.841172892 -0700 @@ -324,7 +324,7 @@ struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); struct xfrm_state *x; - if (type != ICMPV6_DEST_UNREACH || + if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG) return; diff -urN linux-2.6.7-rc3/net/ipv6/exthdrs.c linux-2.6.7/net/ipv6/exthdrs.c --- linux-2.6.7-rc3/net/ipv6/exthdrs.c 2004-06-15 23:10:08.056203124 -0700 +++ linux-2.6.7/net/ipv6/exthdrs.c 2004-06-15 23:10:54.860173692 -0700 @@ -155,7 +155,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp) { struct sk_buff *skb = *skbp; - struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { @@ -217,7 +217,7 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp) { struct sk_buff *skb = *skbp; - struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); struct in6_addr *addr; struct in6_addr daddr; int n, i; @@ -288,7 +288,7 @@ return -1; } *skbp = skb = skb2; - opt = (struct inet6_skb_parm *)skb2->cb; + opt = IP6CB(skb2); hdr = (struct ipv6_rt_hdr *) skb2->h.raw; } @@ -418,7 +418,7 @@ static int ipv6_hop_ra(struct sk_buff *skb, int optoff) { if (skb->nh.raw[optoff+1] == 2) { - ((struct inet6_skb_parm*)skb->cb)->ra = optoff; + IP6CB(skb)->ra = optoff; return 1; } LIMIT_NETDEBUG( @@ -482,7 +482,7 @@ int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) { - ((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr); + IP6CB(skb)->hop = sizeof(struct ipv6hdr); if (ip6_parse_tlv(tlvprochopopt_lst, skb)) return sizeof(struct ipv6hdr); return -1; diff -urN linux-2.6.7-rc3/net/ipv6/ip6_input.c linux-2.6.7/net/ipv6/ip6_input.c --- linux-2.6.7-rc3/net/ipv6/ip6_input.c 2004-06-15 23:10:08.098204892 -0700 +++ linux-2.6.7/net/ipv6/ip6_input.c 2004-06-15 23:10:54.876174366 -0700 @@ -74,7 +74,7 @@ /* Store incoming device index. When the packet will be queued, we cannot refer to skb->dev anymore. */ - ((struct inet6_skb_parm *)skb->cb)->iif = dev->ifindex; + IP6CB(skb)->iif = dev->ifindex; if (skb->len < sizeof(struct ipv6hdr)) goto err; diff -urN linux-2.6.7-rc3/net/ipv6/ip6_output.c linux-2.6.7/net/ipv6/ip6_output.c --- linux-2.6.7-rc3/net/ipv6/ip6_output.c 2004-06-15 23:10:08.100204976 -0700 +++ linux-2.6.7/net/ipv6/ip6_output.c 2004-06-15 23:10:54.877174408 -0700 @@ -107,7 +107,7 @@ } -int ip6_output2(struct sk_buff **pskb) +static int ip6_output2(struct sk_buff **pskb) { struct sk_buff *skb = *pskb; struct dst_entry *dst = skb->dst; @@ -349,7 +349,7 @@ { struct dst_entry *dst = skb->dst; struct ipv6hdr *hdr = skb->nh.ipv6h; - struct inet6_skb_parm *opt =(struct inet6_skb_parm*)skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); if (ipv6_devconf.forwarding == 0) goto error; diff -urN linux-2.6.7-rc3/net/ipv6/ndisc.c linux-2.6.7/net/ipv6/ndisc.c --- linux-2.6.7-rc3/net/ipv6/ndisc.c 2004-06-15 23:10:08.187208638 -0700 +++ linux-2.6.7/net/ipv6/ndisc.c 2004-06-15 23:10:54.913175924 -0700 @@ -395,7 +395,7 @@ ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr); - dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2); + dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); if (!dst) return; @@ -486,7 +486,7 @@ ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr); - dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output2); + dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); if (!dst) return; @@ -562,7 +562,7 @@ ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr); - dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output2); + dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output); if (!dst) return; diff -urN linux-2.6.7-rc3/net/ipv6/raw.c linux-2.6.7/net/ipv6/raw.c --- linux-2.6.7-rc3/net/ipv6/raw.c 2004-06-15 23:10:08.224210196 -0700 +++ linux-2.6.7/net/ipv6/raw.c 2004-06-15 23:10:54.922176303 -0700 @@ -409,10 +409,8 @@ ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); sin6->sin6_flowinfo = 0; sin6->sin6_scope_id = 0; - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; - sin6->sin6_scope_id = opt->iif; - } + if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin6->sin6_scope_id = IP6CB(skb)->iif; } sock_recv_timestamp(msg, sk, skb); diff -urN linux-2.6.7-rc3/net/ipv6/route.c linux-2.6.7/net/ipv6/route.c --- linux-2.6.7-rc3/net/ipv6/route.c 2004-06-15 23:10:08.250211290 -0700 +++ linux-2.6.7/net/ipv6/route.c 2004-06-15 23:10:54.925176430 -0700 @@ -84,6 +84,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static struct dst_entry *ip6_negative_advice(struct dst_entry *); static void ip6_dst_destroy(struct dst_entry *); +static void ip6_dst_ifdown(struct dst_entry *, int how); static int ip6_dst_gc(void); static int ip6_pkt_discard(struct sk_buff *skb); @@ -98,6 +99,7 @@ .gc_thresh = 1024, .check = ip6_dst_check, .destroy = ip6_dst_destroy, + .ifdown = ip6_dst_ifdown, .negative_advice = ip6_negative_advice, .link_failure = ip6_link_failure, .update_pmtu = ip6_rt_update_pmtu, @@ -143,9 +145,17 @@ static void ip6_dst_destroy(struct dst_entry *dst) { struct rt6_info *rt = (struct rt6_info *)dst; - if (rt->rt6i_idev != NULL) - in6_dev_put(rt->rt6i_idev); - + struct inet6_dev *idev = rt->rt6i_idev; + + if (idev != NULL) { + rt->rt6i_idev = NULL; + in6_dev_put(idev); + } +} + +static void ip6_dst_ifdown(struct dst_entry *dst, int how) +{ + ip6_dst_destroy(dst); } /* @@ -573,6 +583,8 @@ /* Protected by rt6_lock. */ static struct dst_entry *ndisc_dst_gc_list; +static int ipv6_get_mtu(struct net_device *dev); +static inline unsigned int ipv6_advmss(unsigned int mtu); struct dst_entry *ndisc_dst_alloc(struct net_device *dev, struct neighbour *neigh, @@ -598,6 +610,8 @@ rt->rt6i_metric = 0; atomic_set(&rt->u.dst.__refcnt, 1); rt->u.dst.metrics[RTAX_HOPLIMIT-1] = 255; + rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); + rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst)); rt->u.dst.output = output; write_lock_bh(&rt6_lock); diff -urN linux-2.6.7-rc3/net/ipv6/tcp_ipv6.c linux-2.6.7/net/ipv6/tcp_ipv6.c --- linux-2.6.7-rc3/net/ipv6/tcp_ipv6.c 2004-06-15 23:10:08.251211332 -0700 +++ linux-2.6.7/net/ipv6/tcp_ipv6.c 2004-06-15 23:10:54.927176514 -0700 @@ -536,8 +536,7 @@ static __inline__ int tcp_v6_iif(struct sk_buff *skb) { - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; - return opt->iif; + return IP6CB(skb)->iif; } static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, @@ -879,7 +878,7 @@ np->rxopt.bits.srcrt == 2 && req->af.v6_req.pktopts) { struct sk_buff *pktopts = req->af.v6_req.pktopts; - struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)pktopts->cb; + struct inet6_skb_parm *rxopt = IP6CB(pktopts); if (rxopt->srcrt) opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt)); } @@ -932,7 +931,7 @@ static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb) { struct ipv6_pinfo *np = inet6_sk(sk); - struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + struct inet6_skb_parm *opt = IP6CB(skb); if (np->rxopt.all) { if ((opt->hop && np->rxopt.bits.hopopts) || @@ -1183,7 +1182,7 @@ goto drop; } - if (tcp_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) + if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1) goto drop; req = tcp_openreq_alloc(); @@ -1300,12 +1299,12 @@ opt = np->opt; - if (tcp_acceptq_is_full(sk)) + if (sk_acceptq_is_full(sk)) goto out_overflow; if (np->rxopt.bits.srcrt == 2 && opt == NULL && req->af.v6_req.pktopts) { - struct inet6_skb_parm *rxopt = (struct inet6_skb_parm *)req->af.v6_req.pktopts->cb; + struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts); if (rxopt->srcrt) opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt)); } diff -urN linux-2.6.7-rc3/net/ipv6/udp.c linux-2.6.7/net/ipv6/udp.c --- linux-2.6.7-rc3/net/ipv6/udp.c 2004-06-15 23:10:08.266211964 -0700 +++ linux-2.6.7/net/ipv6/udp.c 2004-06-15 23:10:54.928176556 -0700 @@ -432,10 +432,8 @@ if (np->rxopt.all) datagram_recv_ctl(sk, msg, skb); - if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) { - struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb; - sin6->sin6_scope_id = opt->iif; - } + if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) + sin6->sin6_scope_id = IP6CB(skb)->iif; } } err = copied; @@ -574,34 +572,26 @@ struct sk_buff *skb) { struct sock *sk, *sk2; - struct sk_buff *buff; int dif; read_lock(&udp_hash_lock); sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); dif = skb->dev->ifindex; sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); - if (!sk) - goto free_skb; + if (!sk) { + kfree_skb(skb); + goto out; + } - buff = NULL; sk2 = sk; while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, uh->source, saddr, dif))) { - if (!buff) { - buff = skb_clone(skb, GFP_ATOMIC); - if (!buff) - continue; - } - if (udpv6_queue_rcv_skb(sk2, buff) >= 0) - buff = NULL; - } - if (buff) - kfree_skb(buff); - if (udpv6_queue_rcv_skb(sk, skb) < 0) { -free_skb: - kfree_skb(skb); + struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); + if (buff) + udpv6_queue_rcv_skb(sk2, buff); } + udpv6_queue_rcv_skb(sk, skb); +out: read_unlock(&udp_hash_lock); } diff -urN linux-2.6.7-rc3/security/dummy.c linux-2.6.7/security/dummy.c --- linux-2.6.7-rc3/security/dummy.c 2004-06-15 23:10:09.824277548 -0700 +++ linux-2.6.7/security/dummy.c 2004-06-15 23:10:56.177229157 -0700 @@ -688,7 +688,7 @@ return 0; } -static int dummy_shm_shmat (struct shmid_kernel *shp, char *shmaddr, +static int dummy_shm_shmat (struct shmid_kernel *shp, char __user *shmaddr, int shmflg) { return 0; diff -urN linux-2.6.7-rc3/security/selinux/hooks.c linux-2.6.7/security/selinux/hooks.c --- linux-2.6.7-rc3/security/selinux/hooks.c 2004-06-15 23:10:09.910281168 -0700 +++ linux-2.6.7/security/selinux/hooks.c 2004-06-15 23:10:56.191229746 -0700 @@ -1380,7 +1380,7 @@ if (error) return; - return secondary_ops->capset_set(target, effective, inheritable, permitted); + secondary_ops->capset_set(target, effective, inheritable, permitted); } static int selinux_capable(struct task_struct *tsk, int cap) @@ -3545,7 +3545,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) { - return msg_msg_free_security(msg); + msg_msg_free_security(msg); } /* message queue security operations */ @@ -3781,7 +3781,7 @@ } static int selinux_shm_shmat(struct shmid_kernel *shp, - char *shmaddr, int shmflg) + char __user *shmaddr, int shmflg) { u32 perms;