# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/18 12:18:59-07:00 torvalds@ppc970.osdl.org # Fix permission problem on include/video/neomagic.h # # include/video/neomagic.h # 2004/04/18 12:18:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Change mode to -rw-r--r-- # # ChangeSet # 2004/04/18 11:14:36-07:00 geert@linux-m68k.org # [PATCH] Amiga Zorro8390 Ethernet KERN_* # # Amiga Zorro8390 Ethernet: Add KERN_* prefixes to printk() messages # # drivers/net/zorro8390.c # 2004/04/16 04:38:09-07:00 geert@linux-m68k.org +11 -9 # Amiga Zorro8390 Ethernet KERN_* # # ChangeSet # 2004/04/18 11:14:22-07:00 geert@linux-m68k.org # [PATCH] Amiga Hydra Ethernet KERN_* # # Amiga Hydra Ethernet: Add KERN_* prefixes to printk() messages # # drivers/net/hydra.c # 2004/04/16 04:24:08-07:00 geert@linux-m68k.org +7 -6 # Amiga Hydra Ethernet KERN_* # # ChangeSet # 2004/04/18 11:14:10-07:00 geert@linux-m68k.org # [PATCH] Amiga Ariadne Ethernet KERN_* # # Amiga Ariadne Ethernet: Add KERN_* prefixes to printk() messages # # drivers/net/ariadne.c # 2004/04/16 04:38:01-07:00 geert@linux-m68k.org +34 -32 # Amiga Ariadne Ethernet KERN_* # # ChangeSet # 2004/04/18 11:13:57-07:00 geert@linux-m68k.org # [PATCH] Amiga A2065 Ethernet debug # # Amiga A2065 Ethernet: Add missing variable in debug code # # drivers/net/a2065.c # 2004/04/16 04:36:50-07:00 geert@linux-m68k.org +1 -0 # Amiga A2065 Ethernet debug # # ChangeSet # 2004/04/18 10:56:22-07:00 akpm@osdl.org # [PATCH] fix visws build # # From: Andrey Panin # # this small patch fixes visws build error in 2.6.5. # # arch/i386/mach-visws/mpparse.c # 2004/04/18 09:13:18-07:00 akpm@osdl.org +4 -0 # fix visws build # # ChangeSet # 2004/04/18 10:56:09-07:00 akpm@osdl.org # [PATCH] Fix laptop mode writeback triggered by hdparm -y. # # From: Bart Samwel # # Currently, an `hdparm -Y' can trigger a sync in laptop mode. We should # only count fs-originated requests as being "disk activity". # # drivers/block/ll_rw_blk.c # 2004/04/18 09:13:18-07:00 akpm@osdl.org +1 -1 # Fix laptop mode writeback triggered by hdparm -y. # # ChangeSet # 2004/04/18 10:55:56-07:00 akpm@osdl.org # [PATCH] set_anon_super locking fix # # Take the idr's lock while removing an element on the error path. Spotted by # Nathan Lynch . # # fs/super.c # 2004/04/18 09:13:18-07:00 akpm@osdl.org +2 -0 # set_anon_super locking fix # # ChangeSet # 2004/04/18 10:55:43-07:00 akpm@osdl.org # [PATCH] Print warning for common symbols in modules # # From: Rusty Russell # # People still build modules wrong, particularly without -fno-common. The # resulting modules don't load, but we should at least warn about it. # # kernel/module.c # 2004/04/18 09:13:18-07:00 akpm@osdl.org +2 -0 # Print warning for common symbols in modules # # ChangeSet # 2004/04/18 10:55:31-07:00 akpm@osdl.org # [PATCH] jbd: journal_dirty_metadata locking speedup # # Reduce the locking coverage of the oft-used j_list_lock: the per-bh # jbd_lock_bh_state() gives us sufficient locking of buffer_head and # journal_head internals. # # fs/jbd/transaction.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +3 -10 # jbd: journal_dirty_metadata locking speedup # # ChangeSet # 2004/04/18 10:55:18-07:00 akpm@osdl.org # [PATCH] rmap: nonlinear truncation # # From: Hugh Dickins # # The earlier changes introducing PageAnon left truncated pages mapped into # nonlinear vmas unswappable. Once we go to object-based rmap, it's # impossible to find where file page is mapped once page->mapping cleared: # switching them to anonymous is odd, and breaks strict commit accounting. # # So now handle truncation of nonlinear vmas correctly. And factor in # Daniel's cluster filesystem needs while we're there: when invalidating # local cache, we do want to unmap shared pages from all mms, but we do not # want to discard private COWed modifications of those pages (which # truncation discards to satisfy the SIGBUS semantics demanded by specs). # # Drew from Daniel's patch (LKML 2 Mar 04), but didn't always follow it; # fewer name changes, but still some - "unmap" rather than "invalidate". # zap_page_range is not exported, safe to give it and all the too-many layers # an extra zap_details arg, in normal cases just NULL. # # Given details, zap_pte_range checks page mapping or index to skip anon or # untruncated pages. I didn't realize before implementing, that in nonlinear # case, it should set a file pte when truncating - otherwise linear pages # might appear in place of SIGBUS. I suspect this implies that ->populate # functions ought to set file ptes beyond EOF instead of failing, but haven't # changed them as yet. # # To avoid making yet another copy of that ugly linear pgidx test, added # inline function linear_page_index (to pagemap.h to get PAGE_CACHE_SIZE, # though as usual things don't really work if it differs from PAGE_SIZE). # Ooh, I thought I'd removed ___add_to_page_cache last time, do so now. # # unmap_page_range static, shift its hugepage check up into sole caller # unmap_vmas. Killed "killme" debug from unmap_vmas, not seen it trigger. # unmap_mapping_range is exported without restriction: I'm one of those who # believe it should be generally available. But I'm wrongly placed to decide # that, probably just sob quietly to myself if _GPL added later. # # mm/shmem.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +1 -5 # rmap: nonlinear truncation # # mm/rmap.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +1 -5 # rmap: nonlinear truncation # # mm/mmap.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +3 -3 # rmap: nonlinear truncation # # mm/memory.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +141 -99 # rmap: nonlinear truncation # # mm/madvise.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +1 -1 # rmap: nonlinear truncation # # mm/filemap.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +2 -6 # rmap: nonlinear truncation # # include/linux/pagemap.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +5 -7 # rmap: nonlinear truncation # # include/linux/mm.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +12 -7 # rmap: nonlinear truncation # # drivers/char/mem.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +1 -1 # rmap: nonlinear truncation # # ChangeSet # 2004/04/18 10:55:06-07:00 akpm@osdl.org # [PATCH] rmap: swap_unplug page # # From: Hugh Dickins # # Good example of "swapper_space considered harmful": swap_unplug_io_fn was # originally designed for calling via swapper_space.backing_dev_info; but # that way it loses track of which device is to be unplugged, so had to # unplug all swap devices. But now sync_page tests SwapCache anyway, can # call swap_unplug_io_fn with page, which leads direct to the device. # # Reverted -mc4's CONFIG_SWAP=n fix, just add another NOTHING for it. # Reverted -mc3's editorial adjustments to swap_backing_dev_info and # swapper_space initializations: they document the few fields which are # actually used now, as comment above them says (sound of slapped wrist). # # mm/swapfile.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +15 -8 # rmap: swap_unplug page # # mm/swap_state.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +2 -2 # rmap: swap_unplug page # # mm/nommu.c # 2004/04/18 09:13:10-07:00 akpm@osdl.org +0 -5 # rmap: swap_unplug page # # mm/filemap.c # 2004/04/18 09:31:45-07:00 akpm@osdl.org +1 -1 # rmap: swap_unplug page # # include/linux/swap.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +2 -3 # rmap: swap_unplug page # # ChangeSet # 2004/04/18 10:54:52-07:00 akpm@osdl.org # [PATCH] rmap: flush_dcache revisited # # From: Hugh Dickins # # One of the callers of flush_dcache_page is do_generic_mapping_read, where # file is read without i_sem and without page lock: concurrent truncation may # at any moment remove page from cache, NULLing ->mapping, making # flush_dcache_page liable to oops. Put result of page_mapping in a local # variable and apply mapping_mapped to that (if we were to check for NULL # within mapping_mapped, it's unclear whether to say yes or no). # # parisc and arm do have other locking unsafety in their i_mmap(_shared) # searching, but that's a larger issue to be dealt with down the line. # # include/asm-sh/pgalloc.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +3 -4 # rmap: flush_dcache revisited # # include/asm-parisc/cacheflush.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +3 -1 # rmap: flush_dcache revisited # # include/asm-arm/cacheflush.h # 2004/04/18 09:13:10-07:00 akpm@osdl.org +3 -1 # rmap: flush_dcache revisited # # arch/sparc64/mm/init.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +2 -1 # rmap: flush_dcache revisited # # arch/parisc/kernel/cache.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +4 -3 # rmap: flush_dcache revisited # # arch/mips/mm/cache.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +2 -1 # rmap: flush_dcache revisited # # arch/arm/mm/fault-armv.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +8 -3 # rmap: flush_dcache revisited # # ChangeSet # 2004/04/18 10:54:39-07:00 akpm@osdl.org # [PATCH] Oprofilefs cant handle > 99 cpus # # From: Anton Blanchard # # Oprofilefs cant handle > 99 cpus. This should fix it. # # drivers/oprofile/oprofile_stats.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +1 -1 # Oprofilefs cant handle > 99 cpus # # ChangeSet # 2004/04/18 10:54:27-07:00 akpm@osdl.org # [PATCH] Fix unix module # # From: Rusty Russell # # # lsmod # Module Size Used by # 1 26060 6 # # # # The compiler #define's unix to 1: we use -DKBUILD_MODNAME=unix. We used to # #undef unix at the top of af_unix.c, but now the name is inserted by # modpost, that doesn't help. # # #undef unix in modpost.c's generated C file. # # scripts/modpost.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +1 -0 # Fix unix module # # net/unix/af_unix.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +0 -2 # Fix unix module # # ChangeSet # 2004/04/18 10:54:15-07:00 akpm@osdl.org # [PATCH] ppc64: Fix CPU hot unplug deadlock # # From: Benjamin Herrenschmidt # # My RTAS locking fixes incorrectly added a spinlock around the function used # to stop a CPU, that function never returns, thus the lock becomes stale. # The correct fix is to disable interrupts instead (the RTAS params beeing # per-CPU, this should be safe enough) # # arch/ppc64/kernel/rtas.c # 2004/04/18 09:13:09-07:00 akpm@osdl.org +2 -3 # ppc64: Fix CPU hot unplug deadlock # # ChangeSet # 2004/04/18 10:51:30-07:00 torvalds@ppc970.osdl.org # Allow non-LFS sendfile to work on LFS files. # # But obviously only if we're not passing in any offset pointer. # # This is how 2.4.x worked, and vsftpd relies on it. # # Bug reported by Chris < chris@scary.beasts.org> # # fs/read_write.c # 2004/04/18 10:51:24-07:00 torvalds@ppc970.osdl.org +1 -1 # Allow non-LFS sendfile to work on LFS files. # # But obviously only if we're not passing in any offset pointer. # # This is how 2.4.x worked, and vsftpd relies on it. # # Bug reported by Chris < chris@scary.beasts.org> # # ChangeSet # 2004/04/17 17:50:14-07:00 hugh@veritas.com # [PATCH] Fix vma corruption # # It occurred to me that if vma and new_vma are one and the same, then # vma_relink_file will not do a good job of linking it after itself - in # that pretty unlikely case when move_page_tables fails. # # And more generally, whenever copy_vma's vma_merge succeeds, we have no # guarantee that old vma comes before new_vma in the i_mmap lists, as we # need to satisfy Rajesh's point: that ordering is only guaranteed in the # newly allocated case. # # We have to abandon the ordering method when/if we move from lists to # prio_trees, so this patch switches to the less glamorous use of # i_shared_sem exclusion, as in my prio_tree mremap. # # mm/mremap.c # 2004/04/17 10:46:31-07:00 hugh@veritas.com +14 -8 # Fix vma corruption # # mm/mmap.c # 2004/04/17 10:46:31-07:00 hugh@veritas.com +11 -23 # Fix vma corruption # # include/linux/mm.h # 2004/04/17 10:46:31-07:00 hugh@veritas.com +1 -2 # Fix vma corruption # # ChangeSet # 2004/04/17 17:45:53-07:00 viro@parcelfarce.linux.theplanet.co.uk # [PATCH] Remove unused 'kobject' from superblock # # The field in question is # a) unused # b) damn next to impossible to use correctly, due to struct super_block # lifetime and locking rules. # # include/linux/fs.h # 2004/04/17 11:09:34-07:00 viro@parcelfarce.linux.theplanet.co.uk +0 -1 # Remove unused 'kobject' from superblock # # ChangeSet # 2004/04/17 17:32:46-07:00 akpm@osdl.org # [PATCH] ARM-related ptep_to_address() fix # # From: William Lee Irwin III # # rmk mentioned that ARM was borked as the relation, assumed by generic rmap, # PTRS_PER_PTE*sizeof(pte_t) == PAGE_SIZE, fails to hold. The following # patch, developed jointly with him (or depending on POV, by him with me # acting as codemonkey), is reported to resolve the issue. # # Specifically, while ARM dedicates an entire PAGE_SIZE -sized block of # memory to each PTE table, the PTE table itself only spans half that, the # remainder being dedicated to hardware-interpreted structures. As the # hardware structure must be contiguous, wider ptes can't be used. So the # core-visible PTE table only spans PAGE_SIZE/2 bytes, violating the # assumption. This corrects masking and scaling done in ptep_to_address(). # # include/asm-generic/rmap.h # 2004/04/17 11:19:32-07:00 akpm@osdl.org +2 -1 # ARM-related ptep_to_address() fix # # ChangeSet # 2004/04/17 17:29:32-07:00 akpm@osdl.org # [PATCH] aty128fb dereference before null check # # From: Dave Jones # # drivers/video/aty/aty128fb.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +3 -1 # aty128fb dereference before null check # # ChangeSet # 2004/04/17 17:29:22-07:00 akpm@osdl.org # [PATCH] mqueue permission fix # # From: Manfred Spraul # # Any user can delete any entries in a mqueue mounted filesystem. The attached # patch prevents that. # # - remove the writable test from mq_unlink. # # - set the sticky bit in the root inode. This affects both mq_unlink and # sys_unlink: only the owner (and root) should be allowed to remove queues. # # ipc/mqueue.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +1 -5 # mqueue permission fix # # ChangeSet # 2004/04/17 17:29:12-07:00 akpm@osdl.org # [PATCH] Fix bogus get_page() calls in hugepage code # # From: David Gibson # # Some versions of follow_huge_addr() and follow_huge_pmd() are doing a # get_page() on the target page. They shouldn't: follow_page() returns an # unpinned page and it is the caller's responsibility to pin the page (if # desired) before dropping page_table_lock. # # arch/ppc64/mm/hugetlbpage.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +1 -3 # Fix bogus get_page() calls in hugepage code # # arch/ia64/mm/hugetlbpage.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +0 -1 # Fix bogus get_page() calls in hugepage code # # arch/i386/mm/hugetlbpage.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +1 -3 # Fix bogus get_page() calls in hugepage code # # ChangeSet # 2004/04/17 17:29:02-07:00 akpm@osdl.org # [PATCH] ppc64: yet another hugepage cleanup # # From: David Gibson # # Trivial cleanup to flush_hash_hugepage() in the ppc64 hugepage code. # # arch/ppc64/mm/hugetlbpage.c # 2004/04/17 11:27:48-07:00 akpm@osdl.org +2 -3 # ppc64: yet another hugepage cleanup # # ChangeSet # 2004/04/17 17:28:52-07:00 akpm@osdl.org # [PATCH] ipmi build fix # # From: Geert Uytterhoeven # # While compiling drivers/char/ipmi/ipmi_si_intf.c in 2.6.6-rc1 on m68k, I # noticed a missing include (needed for disable_irq_nosync() and enable_irq()) # # drivers/char/ipmi/ipmi_si_intf.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +1 -0 # ipmi build fix # # ChangeSet # 2004/04/17 17:28:36-07:00 akpm@osdl.org # [PATCH] floppy98.c build fixes # # From: "Randy.Dunlap" # # floppy98.c (along with other PC-9800 files) has not been updated lately. It # won't build currently (2.6.5). # # This patch makes floppy98 build cleanly. # # drivers/block/floppy98.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +35 -14 # floppy98.c build fixes # # ChangeSet # 2004/04/17 17:28:24-07:00 akpm@osdl.org # [PATCH] reiserfs: remove final sleep_on # # From: Chris Mason # # Get rid of the last sleep_on in the reiserfs code # # fs/reiserfs/journal.c # 2004/04/17 11:19:31-07:00 akpm@osdl.org +13 -1 # reiserfs: remove final sleep_on # # ChangeSet # 2004/04/17 17:28:13-07:00 akpm@osdl.org # [PATCH] reiserfs: fsync() speedup # # From: Chris Mason # # Updates the reiserfs-logging improvements to use schedule_timeout instead of # yield when letting the transaction grow a little before forcing a commit for # fsync/O_SYNC/O_DIRECT. # # Also, when one process forces a transaction to end and plans on doing the # commit (like fsync), it sets a flag on the transaction so the journal code # knows not to bother kicking the journal work queue. # # queue_delayed_work is used so that if we get a bunch of tiny transactions # ended quickly, we aren't constantly kicking the work queue. # # These significantly improve reiserfs performance during fsync heavy # workloads. # # fs/reiserfs/journal.c # 2004/04/17 11:27:49-07:00 akpm@osdl.org +17 -7 # reiserfs: fsync() speedup # # ChangeSet # 2004/04/17 17:28:02-07:00 akpm@osdl.org # [PATCH] Add "commit=0" to reiserfs # # From: Bart Samwel # # Add support for value 0 to the commit option of reiserfs. Means "restore # to the default value". For the maximum commit age, this default value is # normally read from the journal; this patch adds an extra variable to cache # the default value for the maximum commit age. # # include/linux/reiserfs_fs_sb.h # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -0 # Add "commit=0" to reiserfs # # fs/reiserfs/super.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +10 -6 # Add "commit=0" to reiserfs # # fs/reiserfs/journal.c # 2004/04/17 11:27:49-07:00 akpm@osdl.org +1 -0 # Add "commit=0" to reiserfs # # ChangeSet # 2004/04/17 17:27:51-07:00 akpm@osdl.org # [PATCH] ppc64: hugepage cleanup # # From: David Gibson # # This is a small cleanup to the PPC64 hugepage code. It removes an # unhelpful function, removing some studlyCaps in the process. It was # originally this way to match the normal page path, but that has all been # rewritten since. # # arch/ppc64/mm/hugetlbpage.c # 2004/04/17 11:27:48-07:00 akpm@osdl.org +1 -10 # ppc64: hugepage cleanup # # ChangeSet # 2004/04/17 17:27:40-07:00 akpm@osdl.org # [PATCH] Fix mq 32-bit compatibility # # From: Jakub Jelinek # # The first change removes just a useless put_user (si_int and si_ptr are # part of the same union, si_ptr is on all arches covering whole union), the # rest is fixes for signal handling of SI_MESGQ. # # kernel/signal.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -1 # Fix mq 32-bit compatibility # # include/asm-mips/siginfo.h # 2004/04/17 11:19:30-07:00 akpm@osdl.org +1 -1 # Fix mq 32-bit compatibility # # arch/x86_64/ia32/ia32_signal.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -2 # Fix mq 32-bit compatibility # # arch/sparc64/kernel/signal32.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -2 # Fix mq 32-bit compatibility # # arch/s390/kernel/compat_signal.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -2 # Fix mq 32-bit compatibility # # arch/mips/kernel/signal32.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -2 # Fix mq 32-bit compatibility # # arch/ia64/ia32/ia32_signal.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +2 -2 # Fix mq 32-bit compatibility # # ChangeSet # 2004/04/17 17:27:28-07:00 akpm@osdl.org # [PATCH] remove buffer_error() # # From: Jeff Garzik # # It was debug code, no longer required. # # include/linux/buffer_head.h # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -7 # remove buffer_error() # # fs/reiserfs/inode.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -5 # remove buffer_error() # # fs/ntfs/aops.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -2 # remove buffer_error() # # fs/mpage.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +1 -2 # remove buffer_error() # # fs/ext3/inode.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -2 # remove buffer_error() # # fs/buffer.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +7 -93 # remove buffer_error() # # ChangeSet # 2004/04/17 17:27:17-07:00 akpm@osdl.org # [PATCH] PCI MSI Kconfig consolidation # # From: Bjorn Helgaas # # This consolidates the PCI MSI configuration into drivers/pci/Kconfig, # removing it from the i386, x86_64, and ia64 Kconfig. # # It also changes the default for ia64 from "y" to "n". The default on i386 # is "n" already, and I'm not sure why ia64 should be different. # # drivers/pci/Kconfig # 2004/04/17 11:19:30-07:00 akpm@osdl.org +19 -0 # PCI MSI Kconfig consolidation # # arch/x86_64/Kconfig # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -20 # PCI MSI Kconfig consolidation # # arch/ia64/Kconfig # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -10 # PCI MSI Kconfig consolidation # # arch/i386/Kconfig # 2004/04/17 11:19:30-07:00 akpm@osdl.org +0 -19 # PCI MSI Kconfig consolidation # # ChangeSet # 2004/04/17 17:27:06-07:00 akpm@osdl.org # [PATCH] kill submit_{bh,bio} return value # # From: Jeff Garzik # # Nobody ever checks the return value of submit_bh(), and submit_bh() is the # only caller that checks the submit_bio() return value. # # This changes the kernel I/O submission path -- a fast path -- so this # cleanup is also a microoptimization. # # include/linux/fs.h # 2004/04/17 11:19:30-07:00 akpm@osdl.org +1 -1 # kill submit_{bh,bio} return value # # include/linux/buffer_head.h # 2004/04/17 11:27:49-07:00 akpm@osdl.org +1 -1 # kill submit_{bh,bio} return value # # fs/buffer.c # 2004/04/17 11:27:49-07:00 akpm@osdl.org +2 -2 # kill submit_{bh,bio} return value # # drivers/block/ll_rw_blk.c # 2004/04/17 11:19:30-07:00 akpm@osdl.org +1 -2 # kill submit_{bh,bio} return value # # ChangeSet # 2004/04/17 17:26:55-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Implement server-side reboot recovery (mostly) # # From: NeilBrown # # From: "J. Bruce Fields" # # From: Andros: Implement server-side reboot recovery (server now handles # open and lock reclaims). Not completely to spec: we don't yet store the # state in stable storage that would be required to recover correctly in # certain situations. # # include/linux/nfsd/state.h # 2004/04/17 11:19:29-07:00 akpm@osdl.org +2 -0 # kNFSdv4: Implement server-side reboot recovery (mostly) # # include/linux/nfsd/nfsd.h # 2004/04/17 11:19:29-07:00 akpm@osdl.org +3 -0 # kNFSdv4: Implement server-side reboot recovery (mostly) # # fs/nfsd/nfs4state.c # 2004/04/17 11:19:29-07:00 akpm@osdl.org +47 -6 # kNFSdv4: Implement server-side reboot recovery (mostly) # # fs/nfsd/nfs4proc.c # 2004/04/17 11:19:29-07:00 akpm@osdl.org +88 -14 # kNFSdv4: Implement server-side reboot recovery (mostly) # # ChangeSet # 2004/04/17 17:26:39-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Set credentials properly when puutrootfh is used # # From: NeilBrown # # The credentials (uid/gid) of a process are set when a filehandle is # verified. Nfsv4 allows requests without an explicit filehandle (instead, # an implicit 'root' filehandle) so we much make sure the credentials are set # for these requests too. # # From: "J. Bruce Fields" # # From: Andros: added a call to nfsd_setuser in nfsd4_putrootfh so that nfsd # runs as the rpc->cred user. # # fs/nfsd/nfs4proc.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +6 -1 # kNFSdv4: Set credentials properly when puutrootfh is used # # ChangeSet # 2004/04/17 17:26:28-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Improve how locking copes with replays # # From: NeilBrown # # From: "J. Bruce Fields" # # From: Andros: Hold state_lock longer so the stateowner doesn't diseappear # out from under us before we get the chance to encode the replay. Don't # attempt to save replay if we failed to find a stateowner. # # fs/nfsd/nfs4xdr.c # 2004/04/17 11:19:29-07:00 akpm@osdl.org +21 -12 # kNFSdv4: Improve how locking copes with replays # # fs/nfsd/nfs4state.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +23 -10 # kNFSdv4: Improve how locking copes with replays # # fs/nfsd/nfs4proc.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +27 -8 # kNFSdv4: Improve how locking copes with replays # # ChangeSet # 2004/04/17 17:26:12-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Allow locku replays aswell # # From: NeilBrown # # From: "J. Bruce Fields" # # From: Andros: locku replies should be saved for possible replay as well. # # fs/nfsd/nfs4proc.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +1 -0 # kNFSdv4: Allow locku replays aswell # # ChangeSet # 2004/04/17 17:25:57-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Keep state to allow replays for 'close' to work. # # From: NeilBrown # # From: "J. Bruce Fields" # # From: Andros: Idea is to keep around a list of openowners recently released # by closes, and make sure they stay around long enough so that replays still # work. # # include/linux/nfsd/state.h # 2004/04/17 11:27:50-07:00 akpm@osdl.org +6 -0 # kNFSdv4: Keep state to allow replays for 'close' to work. # # fs/nfsd/nfs4state.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +78 -71 # kNFSdv4: Keep state to allow replays for 'close' to work. # # ChangeSet # 2004/04/17 17:25:42-07:00 akpm@osdl.org # [PATCH] kNFSdv4: Fix bad error returm from svcauth_gss_accept # # From: NeilBrown # # From: "J. Bruce Fields" # # Error return when the client supplies a bad service should be badcred. # # net/sunrpc/auth_gss/svcauth_gss.c # 2004/04/17 11:19:29-07:00 akpm@osdl.org +1 -0 # kNFSdv4: Fix bad error returm from svcauth_gss_accept # # ChangeSet # 2004/04/17 17:25:31-07:00 akpm@osdl.org # [PATCH] kNFSdv4: nfsd4_readdir fixes # # From: NeilBrown # # From: "J. Bruce Fields" # # Fix out-of-spec errors in nfs4 readdir. Add checks for bad cookie values. # # (plus compile fix from akpm) # # fs/nfsd/nfs4xdr.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +2 -0 # kNFSdv4: nfsd4_readdir fixes # # fs/nfsd/nfs4proc.c # 2004/04/17 11:27:50-07:00 akpm@osdl.org +5 -1 # kNFSdv4: nfsd4_readdir fixes # # ChangeSet # 2004/04/17 17:25:21-07:00 akpm@osdl.org # [PATCH] dm: Use an EMIT macro in the status function. # # From: Kevin Corry # # Striped: Use an EMIT macro in the status function. # # drivers/md/dm-stripe.c # 2004/04/17 11:19:28-07:00 akpm@osdl.org +7 -7 # dm: Use an EMIT macro in the status function. # # ChangeSet # 2004/04/17 17:25:10-07:00 akpm@osdl.org # [PATCH] dm: avoid ioctl buffer overrun # # From: Kevin Corry # # dm-ioctl.c::retrieve_status(): Prevent overrunning the ioctl buffer by making # sure we don't call the target status routine with a buffer size limit of # zero. [Kevin Corry, Alasdair Kergon] # # drivers/md/dm-ioctl.c # 2004/04/17 11:19:28-07:00 akpm@osdl.org +5 -1 # dm: avoid ioctl buffer overrun # # ChangeSet # 2004/04/17 17:24:54-07:00 akpm@osdl.org # [PATCH] dm: fix a comment # # From: Kevin Corry # # Clarify the comment regarding the "next" field in struct dm_target_spec. The # "next" field has different behavior if you're performing a DM_TABLE_STATUS # command than it does if you're performing a DM_TABLE_LOAD command. # # See populate_table() and retrieve_status() in drivers/md/dm-ioctl.c for more # details on how this field is used. # # include/linux/dm-ioctl.h # 2004/04/17 11:19:28-07:00 akpm@osdl.org +8 -2 # dm: fix a comment # # ChangeSet # 2004/04/17 17:24:39-07:00 akpm@osdl.org # [PATCH] dm: Correctly align the dm_target_spec structures during retrieve_status(). # # From: Kevin Corry # # Correctly align the dm_target_spec structures during retrieve_status(). # # drivers/md/dm-ioctl.c # 2004/04/17 11:27:51-07:00 akpm@osdl.org +1 -1 # dm: Correctly align the dm_target_spec structures during retrieve_status(). # # ChangeSet # 2004/04/17 17:24:28-07:00 akpm@osdl.org # [PATCH] dm: Log an error if the target has unknown target type, or zero length. # # From: Kevin Corry # # Log an error if the target has unknown target type, or zero length. # # drivers/md/dm-table.c # 2004/04/17 11:19:28-07:00 akpm@osdl.org +3 -1 # dm: Log an error if the target has unknown target type, or zero length. # # ChangeSet # 2004/04/17 17:24:16-07:00 akpm@osdl.org # [PATCH] dm: Use wake_up() rather than wake_up_interruptible() # # From: Kevin Corry # # dm.c: Use wake_up() rather than wake_up_interruptible() with the eventq. # # drivers/md/dm.c # 2004/04/17 11:19:28-07:00 akpm@osdl.org +1 -1 # dm: Use wake_up() rather than wake_up_interruptible() # # ChangeSet # 2004/04/17 17:24:04-07:00 akpm@osdl.org # [PATCH] dm: Handle interrupts within suspend. # # From: Kevin Corry # # Handle interrupts within suspend. # # drivers/md/dm.c # 2004/04/17 11:27:51-07:00 akpm@osdl.org +9 -1 # dm: Handle interrupts within suspend. # # ChangeSet # 2004/04/17 17:23:52-07:00 akpm@osdl.org # [PATCH] dm: Check the uptodate flag in sub-bios to see if there was an error. # # From: Kevin Corry # # Check the uptodate flag in sub-bios to see if there was an error. [Mike # Christie] # # drivers/md/dm.c # 2004/04/17 11:27:52-07:00 akpm@osdl.org +3 -0 # dm: Check the uptodate flag in sub-bios to see if there was an error. # # ChangeSet # 2004/04/17 17:23:39-07:00 akpm@osdl.org # [PATCH] dm: Fix 64/32 bit ioctl problems. # # From: Kevin Corry # # Fix 64/32 bit ioctl problems. # # include/linux/dm-ioctl.h # 2004/04/17 11:27:51-07:00 akpm@osdl.org +28 -0 # dm: Fix 64/32 bit ioctl problems. # # include/linux/compat_ioctl.h # 2004/04/17 11:19:27-07:00 akpm@osdl.org +13 -0 # dm: Fix 64/32 bit ioctl problems. # # ChangeSet # 2004/04/17 17:08:23-07:00 vandrove@vc.cvut.cz # [PATCH] Fix exec in multithreaded application # # The recent controlling terminal changes broke exec from multithreaded # application because de_thread was not upgraded to new arrangement. I # know that I should not have LD_PRELOAD library which automatically # creates one thread, but it looked like a cool solution to the problem I # had. # # de_thread must initialize the controlling terminal information in the # new thread group. # # fs/exec.c # 2004/04/17 12:09:53-07:00 vandrove@vc.cvut.cz +2 -0 # Fix exec in multithreaded application # # ChangeSet # 2004/04/17 22:19:03+01:00 rmk@flint.arm.linux.org.uk # [ARM] Add detailed documentation concerning ARM page tables # # This adds detailed documentation concerning how we map the Linux # page table structure onto the hardware tables on ARM. In addition, # it also adds documentation describing how we emulate the "dirty" # and "young" or "accessed" page table bits. # # This should be of interest to Linux MM developers. # # include/asm-arm/pgtable.h # 2004/04/17 22:17:13+01:00 rmk@flint.arm.linux.org.uk +56 -7 # Add detailed documentation concerning ARM page tables and how the # dirty and young bits are emulated. # # ChangeSet # 2004/04/17 11:08:39+01:00 rmk@flint.arm.linux.org.uk # [SERIAL] Use module_param/module_param_array # # Update serial to use new module parameters rather than # MODULE_PARM. # # drivers/serial/serial_cs.c # 2004/04/17 11:04:24+01:00 rmk@flint.arm.linux.org.uk +9 -7 # Use module_param/module_param_array # # drivers/serial/8250.c # 2004/04/17 10:48:54+01:00 rmk@flint.arm.linux.org.uk +11 -15 # Use module_param/module_param_array # # ChangeSet # 2004/04/17 10:31:25+01:00 rmk@flint.arm.linux.org.uk # [SERIAL] Remove check_region() # # drivers/serial/8250.c # 2004/04/17 10:28:52+01:00 rmk@flint.arm.linux.org.uk +3 -5 # Remove check_region() # # ChangeSet # 2004/04/17 09:41:18+01:00 proski@org.rmk.(none) # [PCMCIA] Conversion to module_param # # Patch from: Pavel Roskin # # As it turns out, mixing MODULE_PARM and module_param in one module is # wrong. The parameters specified in module_param are ignored. I've just # posted a patch to LKML that will detect this condition and warn about it. # # The new debugging code used the new-style module_param, which means that # all instances of MODULE_PARM should be converted. The attached patch does # that. # # An additional bonus is that module_param_array provides the number of # array elements. This allowed me to change tcic.c and i82365.c to use # this number for IRQ list. This change was tested with i82365. If # "irq_list" is not specified, irq_list_count is 0. # # I set all permissions to 0444 to be safe. I think we have no secrets # from the users regarding those parameters. If some parameters can be # changed safely at the runtime, the permissions could be changed to 0644. # I didn't examine how safe (and how useful) it would be, so it's 0444 for # now. # # drivers/pcmcia/tcic.c # 2004/04/17 09:36:26+01:00 proski@org.rmk.(none) +13 -13 # [PATCH] Conversion to module_param # # drivers/pcmcia/rsrc_mgr.c # 2004/04/17 09:36:25+01:00 proski@org.rmk.(none) +2 -1 # [PATCH] Conversion to module_param # # drivers/pcmcia/i82365.c # 2004/04/17 09:36:21+01:00 proski@org.rmk.(none) +25 -24 # [PATCH] Conversion to module_param # # drivers/pcmcia/cs.c # 2004/04/17 09:36:19+01:00 proski@org.rmk.(none) +1 -1 # [PATCH] Conversion to module_param # # drivers/pcmcia/cistpl.c # 2004/04/17 09:36:15+01:00 proski@org.rmk.(none) +2 -1 # [PATCH] Conversion to module_param # # ChangeSet # 2004/04/16 22:50:51-07:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/network-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/core/sock.c # 2004/04/16 22:50:43-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/net/sock.h # 2004/04/16 22:50:43-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/04/16 22:29:09-07:00 davem@nuts.davemloft.net # [IPV6]: Fix esp6.c typo in LIMIT_NETDEBUG changes. # # net/ipv6/esp6.c # 2004/04/16 22:28:52-07:00 davem@nuts.davemloft.net +1 -2 # [IPV6]: Fix esp6.c typo in LIMIT_NETDEBUG changes. # # fs/openpromfs/inode.c # 2004/04/16 17:59:25-07:00 marcel@holtmann.org +1 -1 # Fix typo in the openpromfs remount patch # # ChangeSet # 2004/04/16 17:50:41-07:00 torvalds@ppc970.osdl.org # Merge evo:v2.6/linux into ppc970.osdl.org:/home/torvalds/v2.6/linux # # net/core/sock.c # 2004/04/16 17:50:38-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # include/net/sock.h # 2004/04/16 17:50:38-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/04/16 17:49:32-07:00 torvalds@evo.osdl.org # Add sparse __safe annotation # # include/linux/compiler.h # 2004/04/16 17:49:22-07:00 torvalds@evo.osdl.org +2 -0 # Add sparse __safe annotation # # ChangeSet # 2004/04/16 17:48:52-07:00 torvalds@evo.osdl.org # Make sock_no_{get|set}opt() use the proper __user annotation # # net/core/sock.c # 2004/04/16 17:48:47-07:00 torvalds@evo.osdl.org +2 -2 # Make sock_no_{get|set}opt() use the proper __user annotation # # include/net/sock.h # 2004/04/16 17:48:47-07:00 torvalds@evo.osdl.org +2 -2 # Make sock_no_{get|set}opt() use the proper __user annotation # # ChangeSet # 2004/04/16 16:18:05-07:00 marcel@holtmann.org # [PATCH] Fix typo in the openpromfs remount patch # # The just merged openpromfs remount patch contains a silly typo in the # field of the super_operations structure. # # Fixed like this. # # ChangeSet # 2004/04/16 16:17:28-07:00 torvalds@ppc970.osdl.org # Merge bk://gkernel.bkbits.net/misc-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # MAINTAINERS # 2004/04/16 16:17:25-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/04/16 16:16:31-07:00 torvalds@ppc970.osdl.org # Merge bk://gkernel.bkbits.net/net-drivers-2.6 # into ppc970.osdl.org:/home/torvalds/v2.6/linux # # drivers/net/sk_mca.c # 2004/04/16 16:16:28-07:00 torvalds@ppc970.osdl.org +0 -2 # Auto merged # # drivers/net/Kconfig # 2004/04/16 16:16:28-07:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # ChangeSet # 2004/04/16 15:55:37-07:00 davem@nuts.davemloft.net # [BRIDGE]: br_fdb.c needs init.h # # net/bridge/br_fdb.c # 2004/04/16 15:55:21-07:00 davem@nuts.davemloft.net +1 -0 # [BRIDGE]: br_fdb.c needs init.h # # ChangeSet # 2004/04/16 15:03:33-07:00 davej@redhat.com # [PATCH] Fix mprotect bogus check. # # If we want to trap NULL vma's, we'd better be sure # that we don't dereference it first.. # # mm/mprotect.c # 2004/04/16 13:53:12-07:00 davej@redhat.com +2 -1 # Fix mprotect bogus check. # # ChangeSet # 2004/04/16 15:03:20-07:00 davej@redhat.com # [PATCH] Fix edd driver dereferencing before pointer checks. # # Lots of occurences of the same bug.. # # drivers/firmware/edd.c # 2004/04/16 13:47:57-07:00 davej@redhat.com +110 -57 # Fix edd driver dereferencing before pointer checks. # # ChangeSet # 2004/04/16 15:03:09-07:00 B.Zolnierkiewicz@elka.pw.edu.pl # [PATCH] ide-probe.c: SanDisk is flash # # From: Meelis Roos # # This is self-explanatory - former SunDisk renamed itself to SanDisk and # now there are flash disks with both names. # # drivers/ide/ide-probe.c # 2004/04/16 12:17:59-07:00 B.Zolnierkiewicz@elka.pw.edu.pl +2 -1 # ide-probe.c: SanDisk is flash # # ChangeSet # 2004/04/16 14:59:31-07:00 shemminger@osdl.org # [NET]: Fix lapbether bad scheduling while atomic. # # Bring up/down network devices with lapbether causes scheduling while # atomic (if preempt enabled). # # The calls to rcu_read_lock are unnecessary since lapb_device_event # is called from notifier with the rtnetlink semaphore held, it is # already protected from the labp_devices list changing. # # drivers/net/wan/lapbether.c # 2004/04/16 14:59:18-07:00 shemminger@osdl.org +2 -2 # [NET]: Fix lapbether bad scheduling while atomic. # # Bring up/down network devices with lapbether causes scheduling while # atomic (if preempt enabled). # # The calls to rcu_read_lock are unnecessary since lapb_device_event # is called from notifier with the rtnetlink semaphore held, it is # already protected from the labp_devices list changing. # # ChangeSet # 2004/04/16 14:53:50-07:00 takamiya@po.ntts.co.jp # [IPV6]: Fix OOPS in udp6 with extension headers using ancillary data. # # net/ipv6/udp.c # 2004/04/16 14:53:37-07:00 takamiya@po.ntts.co.jp +1 -0 # [IPV6]: Fix OOPS in udp6 with extension headers using ancillary data. # # ChangeSet # 2004/04/16 14:52:22-07:00 nakam@linux-ipv6.org # [IPV6]: Fix IPSEC AH typo. # # net/ipv6/ah6.c # 2004/04/16 14:52:10-07:00 nakam@linux-ipv6.org +1 -1 # [IPV6]: Fix IPSEC AH typo. # # ChangeSet # 2004/04/16 14:51:15-07:00 yoshfuji@linux-ipv6.org # [IPV6]: Use IANA icmpv6 type for MLDv2 report. # # include/linux/icmpv6.h # 2004/04/16 14:51:03-07:00 yoshfuji@linux-ipv6.org +1 -2 # [IPV6]: Use IANA icmpv6 type for MLDv2 report. # # ChangeSet # 2004/04/16 14:50:17-07:00 jt@bougret.hpl.hp.com # [IRDA]: Replace sleep_on with wait_event # # From Stephen Hemminger. # # net/irda/irlan/irlan_eth.c # 2004/04/16 14:50:04-07:00 jt@bougret.hpl.hp.com +4 -4 # [IRDA]: Replace sleep_on with wait_event # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:49:46-07:00 jt@bougret.hpl.hp.com # [IRDA]: irlan_eth cleanup. # # Use IrTTP flow control to stop/wake netif # From Stephen Hemminger. # Change irlan_eth device initialization: # *bug* address never set in DIRECT mode because access not set # in alloc_netdev -> irlan_eth_setup path # + make eth_XXX handles static and provide alloc_irlandev hook # + use netdev_priv (and get rid of truly impossible ASSERT's) # + use skb_queue_purge # # net/irda/irlan/irlan_eth.c # 2004/04/16 14:49:34-07:00 jt@bougret.hpl.hp.com +57 -75 # [IRDA]: irlan_eth cleanup. # # Use IrTTP flow control to stop/wake netif # From Stephen Hemminger. # Change irlan_eth device initialization: # *bug* address never set in DIRECT mode because access not set # in alloc_netdev -> irlan_eth_setup path # + make eth_XXX handles static and provide alloc_irlandev hook # + use netdev_priv (and get rid of truly impossible ASSERT's) # + use skb_queue_purge # # net/irda/irlan/irlan_common.c # 2004/04/16 14:49:34-07:00 jt@bougret.hpl.hp.com +21 -9 # [IRDA]: irlan_eth cleanup. # # Use IrTTP flow control to stop/wake netif # From Stephen Hemminger. # Change irlan_eth device initialization: # *bug* address never set in DIRECT mode because access not set # in alloc_netdev -> irlan_eth_setup path # + make eth_XXX handles static and provide alloc_irlandev hook # + use netdev_priv (and get rid of truly impossible ASSERT's) # + use skb_queue_purge # # include/net/irda/irlan_eth.h # 2004/04/16 14:49:34-07:00 jt@bougret.hpl.hp.com +1 -8 # [IRDA]: irlan_eth cleanup. # # Use IrTTP flow control to stop/wake netif # From Stephen Hemminger. # Change irlan_eth device initialization: # *bug* address never set in DIRECT mode because access not set # in alloc_netdev -> irlan_eth_setup path # + make eth_XXX handles static and provide alloc_irlandev hook # + use netdev_priv (and get rid of truly impossible ASSERT's) # + use skb_queue_purge # # ChangeSet # 2004/04/16 14:48:29-07:00 jt@bougret.hpl.hp.com # [IRDA]: irlan_common cleanup. # # Minor type changes in irlan_common for clarity: # - use const # - init and exit can be static # - use skb_queue_purge to flush queue # - get rid of noisy old comment # # From Stephen Hemminger. # # net/irda/irlan/irlan_common.c # 2004/04/16 14:48:16-07:00 jt@bougret.hpl.hp.com +5 -21 # [IRDA]: irlan_common cleanup. # # Minor type changes in irlan_common for clarity: # - use const # - init and exit can be static # - use skb_queue_purge to flush queue # - get rid of noisy old comment # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:47:38-07:00 jt@bougret.hpl.hp.com # [IRDA]: Rename handle_filter_request to irlan_filter_request. # # From Stephen Hemminger. # # net/irda/irlan/irlan_provider.c # 2004/04/16 14:47:25-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Rename handle_filter_request to irlan_filter_request. # # From Stephen Hemminger. # # net/irda/irlan/irlan_filter.c # 2004/04/16 14:47:25-07:00 jt@bougret.hpl.hp.com +2 -2 # [IRDA]: Rename handle_filter_request to irlan_filter_request. # # From Stephen Hemminger. # # include/net/irda/irlan_filter.h # 2004/04/16 14:47:25-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Rename handle_filter_request to irlan_filter_request. # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:47:03-07:00 jt@bougret.hpl.hp.com # [IRDA]: Fix namespace pollution of print_ret_code. # # From Stephen Hemminger. # # net/irda/irlan/irlan_common.c # 2004/04/16 14:46:51-07:00 jt@bougret.hpl.hp.com +0 -45 # [IRDA]: Fix namespace pollution of print_ret_code. # # From Stephen Hemminger. # # net/irda/irlan/irlan_client.c # 2004/04/16 14:46:50-07:00 jt@bougret.hpl.hp.com +46 -0 # [IRDA]: Fix namespace pollution of print_ret_code. # # From Stephen Hemminger. # # include/net/irda/irlan_common.h # 2004/04/16 14:46:50-07:00 jt@bougret.hpl.hp.com +0 -1 # [IRDA]: Fix namespace pollution of print_ret_code. # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:46:32-07:00 jt@bougret.hpl.hp.com # [IRDA]: Get rid of local CRC table in donauboe. # # From Stephen Hemminger. # # drivers/net/irda/donauboe.c # 2004/04/16 14:46:19-07:00 jt@bougret.hpl.hp.com +0 -45 # [IRDA]: Get rid of local CRC table in donauboe. # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:45:58-07:00 jt@bougret.hpl.hp.com # [IRDA]: Fix handling of RD:RSP to be spec compliant # # From Martin Diehl. # # net/irda/irlap_event.c # 2004/04/16 14:45:46-07:00 jt@bougret.hpl.hp.com +19 -0 # [IRDA]: Fix handling of RD:RSP to be spec compliant # # From Martin Diehl. # # ChangeSet # 2004/04/16 14:45:26-07:00 jt@bougret.hpl.hp.com # [IRDA]: Convert vlsi_ir /proc/driver to seq_file. # # From Stephen Hemminger. # # drivers/net/irda/vlsi_ir.c # 2004/04/16 14:45:14-07:00 jt@bougret.hpl.hp.com +74 -188 # [IRDA]: Convert vlsi_ir /proc/driver to seq_file. # # From Stephen Hemminger. # # ChangeSet # 2004/04/16 14:27:54-07:00 viro@www.linux.org.uk # [PATCH] remount: mount flags filtering # # - we could pass MS_ACTIVE in mount flags and it would be passed into # ->get_sb(), leading to interesting failure modes. This flag is only # for internal use (it's set once fill_super is complete and reset # before the inode eviction on umount); made sure that we never get # tricked into having it set it too early. # # fs/namespace.c # 2004/04/16 08:39:38-07:00 viro@www.linux.org.uk +1 -1 # remount: mount flags filtering # # ChangeSet # 2004/04/16 14:27:41-07:00 viro@www.linux.org.uk # [PATCH] remount: forced-nodiratime filesystems # # - a bunch of filesystems force MS_NODIRATIME on mount but forgot to do # the same on remount. Fixed. # # fs/smbfs/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/proc/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/ncpfs/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/jffs/inode-v23.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/hfs/super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +1 -0 # remount: forced-nodiratime filesystems # # fs/fat/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/coda/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/cifs/cifsfs.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-nodiratime filesystems # # fs/affs/super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +2 -0 # remount: forced-nodiratime filesystems # # fs/adfs/super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +1 -0 # remount: forced-nodiratime filesystems # # ChangeSet # 2004/04/16 14:27:28-07:00 viro@www.linux.org.uk # [PATCH] remount: forced-ro filesystems # # - a bunch of r/o filesystems did force MS_RDONLY on mount but forgot to # do the same on remount. Fixed. # # fs/romfs/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-ro filesystems # # fs/qnx4/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +4 -0 # remount: forced-ro filesystems # # fs/isofs/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +8 -0 # remount: forced-ro filesystems # # fs/freevxfs/vxfs_super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +8 -0 # remount: forced-ro filesystems # # fs/efs/super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-ro filesystems # # fs/cramfs/inode.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +7 -0 # remount: forced-ro filesystems # # ChangeSet # 2004/04/16 14:27:14-07:00 viro@www.linux.org.uk # [PATCH] remount: fs/jffs2 # # - jff2->remount_fs() was buggy - it played with sb->s_flags instead of # doing modifications to *flags (->s_flags will be overwritten using # *flags right after the call of ->remount_fs()). Moreover, it tried # to do the wrong thing - it should just enforce noatime and be done # with that. Fixed, ACKed by maintainer. # # fs/jffs2/super.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +1 -1 # remount: fs/jffs2 # # fs/jffs2/fs.c # 2004/04/16 08:39:37-07:00 viro@www.linux.org.uk +1 -1 # remount: fs/jffs2 # # ChangeSet # 2004/04/16 14:27:00-07:00 viro@www.linux.org.uk # [PATCH] remount: fs/openpromfs # # - we should force noatime both on mount and remount. Fixed. # # fs/openpromfs/inode.c # 2004/04/16 08:39:36-07:00 viro@www.linux.org.uk +8 -1 # remount: fs/openpromfs # # ChangeSet # 2004/04/16 14:26:48-07:00 viro@www.linux.org.uk # [PATCH] remount: fs/udf fixes # # - same problem as with sysv - mount-time checks for fs being good for # writing are absent on remount. Check added. # # fs/udf/super.c # 2004/04/16 08:39:36-07:00 viro@www.linux.org.uk +6 -0 # remount: fs/udf fixes # # ChangeSet # 2004/04/16 14:26:34-07:00 viro@www.linux.org.uk # [PATCH] remount: fs/sysv fixes # # - several variants of sysv fs are supported only r/o. Driver does # force r/o on mount, but doesn't do anything on remount. As the # result, one can remount them r/w and results are Not Pretty(tm). # Missing checks added, code cleaned up. # # - we had double-brelse() in v7fs - if sanity checks on root inode will # succeed, but allocation of root dentry fails, we brelse() the same # buffer_head twice. Fixed. # # fs/sysv/sysv.h # 2004/04/16 08:39:35-07:00 viro@www.linux.org.uk +1 -0 # remount: fs/sysv fixes # # fs/sysv/super.c # 2004/04/16 08:39:35-07:00 viro@www.linux.org.uk +5 -3 # remount: fs/sysv fixes # # fs/sysv/inode.c # 2004/04/16 08:39:35-07:00 viro@www.linux.org.uk +11 -0 # remount: fs/sysv fixes # # ChangeSet # 2004/04/16 14:23:28-07:00 shemminger@osdl.org # [BRIDGE]: Replace CLEAR_BITMAP with memset. # # net/bridge/br_if.c # 2004/04/16 14:23:15-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Replace CLEAR_BITMAP with memset. # # ChangeSet # 2004/04/16 14:22:49-07:00 shemminger@osdl.org # [BRIDGE]: FDB cache alloc. # # Since forwarding database gets a lot of memory alloc/free on a busy # bridge, use kmem_cache_alloc to provide cache and better stats. # # net/bridge/br_private.h # 2004/04/16 14:22:36-07:00 shemminger@osdl.org +2 -0 # [BRIDGE]: FDB cache alloc. # # Since forwarding database gets a lot of memory alloc/free on a busy # bridge, use kmem_cache_alloc to provide cache and better stats. # # net/bridge/br_fdb.c # 2004/04/16 14:22:36-07:00 shemminger@osdl.org +20 -4 # [BRIDGE]: FDB cache alloc. # # Since forwarding database gets a lot of memory alloc/free on a busy # bridge, use kmem_cache_alloc to provide cache and better stats. # # net/bridge/br.c # 2004/04/16 14:22:36-07:00 shemminger@osdl.org +3 -0 # [BRIDGE]: FDB cache alloc. # # Since forwarding database gets a lot of memory alloc/free on a busy # bridge, use kmem_cache_alloc to provide cache and better stats. # # ChangeSet # 2004/04/16 14:21:57-07:00 shemminger@osdl.org # [BRIDGE]: Support lots of 1k ports. # # Support >256 ports on a bridge. Use the suggestion of reducing # the number of bits of priority and increasing the number of bits # for port number. # # Easy to increase to even larger if necessary. # # net/bridge/br_stp_if.c # 2004/04/16 14:21:44-07:00 shemminger@osdl.org +11 -7 # [BRIDGE]: Support lots of 1k ports. # # Support >256 ports on a bridge. Use the suggestion of reducing # the number of bits of priority and increasing the number of bits # for port number. # # Easy to increase to even larger if necessary. # # net/bridge/br_private.h # 2004/04/16 14:21:44-07:00 shemminger@osdl.org +3 -0 # [BRIDGE]: Support lots of 1k ports. # # Support >256 ports on a bridge. Use the suggestion of reducing # the number of bits of priority and increasing the number of bits # for port number. # # Easy to increase to even larger if necessary. # # net/bridge/br_ioctl.c # 2004/04/16 14:21:44-07:00 shemminger@osdl.org +14 -5 # [BRIDGE]: Support lots of 1k ports. # # Support >256 ports on a bridge. Use the suggestion of reducing # the number of bits of priority and increasing the number of bits # for port number. # # Easy to increase to even larger if necessary. # # net/bridge/br_if.c # 2004/04/16 14:21:44-07:00 shemminger@osdl.org +14 -13 # [BRIDGE]: Support lots of 1k ports. # # Support >256 ports on a bridge. Use the suggestion of reducing # the number of bits of priority and increasing the number of bits # for port number. # # Easy to increase to even larger if necessary. # # ChangeSet # 2004/04/16 14:21:12-07:00 shemminger@osdl.org # [BRIDGE]: STP unsigned fields. # # Use correct types for fields related to spanning tree protocols. # * costs are 32 bit unsigned # * ports are 16 bit unsigned # * booleans are bytes rather than bitfield # * arrange for better packing # # net/bridge/br_stp_if.c # 2004/04/16 14:21:00-07:00 shemminger@osdl.org +3 -3 # [BRIDGE]: STP unsigned fields. # # Use correct types for fields related to spanning tree protocols. # * costs are 32 bit unsigned # * ports are 16 bit unsigned # * booleans are bytes rather than bitfield # * arrange for better packing # # net/bridge/br_stp.c # 2004/04/16 14:21:00-07:00 shemminger@osdl.org +3 -5 # [BRIDGE]: STP unsigned fields. # # Use correct types for fields related to spanning tree protocols. # * costs are 32 bit unsigned # * ports are 16 bit unsigned # * booleans are bytes rather than bitfield # * arrange for better packing # # net/bridge/br_private.h # 2004/04/16 14:20:59-07:00 shemminger@osdl.org +25 -25 # [BRIDGE]: STP unsigned fields. # # Use correct types for fields related to spanning tree protocols. # * costs are 32 bit unsigned # * ports are 16 bit unsigned # * booleans are bytes rather than bitfield # * arrange for better packing # # ChangeSet # 2004/04/16 14:19:54-07:00 shemminger@osdl.org # [BRIDGE]: Forwarding database changes. # # Make forwarding database more robust. # + Don't insert invalid ether address, # + Report errors back so adding an interface to bridge can fail # + get rid of unneeded explicit pads in data structure # + replace bitfields with byte's for simple booleans. # # net/bridge/br_private.h # 2004/04/16 14:19:27-07:00 shemminger@osdl.org +6 -7 # [BRIDGE]: Forwarding database changes. # # Make forwarding database more robust. # + Don't insert invalid ether address, # + Report errors back so adding an interface to bridge can fail # + get rid of unneeded explicit pads in data structure # + replace bitfields with byte's for simple booleans. # # net/bridge/br_if.c # 2004/04/16 14:19:27-07:00 shemminger@osdl.org +3 -1 # [BRIDGE]: Forwarding database changes. # # Make forwarding database more robust. # + Don't insert invalid ether address, # + Report errors back so adding an interface to bridge can fail # + get rid of unneeded explicit pads in data structure # + replace bitfields with byte's for simple booleans. # # net/bridge/br_fdb.c # 2004/04/16 14:19:27-07:00 shemminger@osdl.org +13 -3 # [BRIDGE]: Forwarding database changes. # # Make forwarding database more robust. # + Don't insert invalid ether address, # + Report errors back so adding an interface to bridge can fail # + get rid of unneeded explicit pads in data structure # + replace bitfields with byte's for simple booleans. # # ChangeSet # 2004/04/16 14:15:24-07:00 shemminger@osdl.org # [BRIDGE]: Multicast address as const. # # net/bridge/br_stp_if.c # 2004/04/16 14:15:11-07:00 shemminger@osdl.org +4 -5 # [BRIDGE]: Multicast address as const. # # net/bridge/br_private.h # 2004/04/16 14:15:11-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Multicast address as const. # # net/bridge/br_input.c # 2004/04/16 14:15:11-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Multicast address as const. # # ChangeSet # 2004/04/16 14:14:41-07:00 shemminger@osdl.org # [BRIDGE]: Use ethtool to get port speed. # # The bridge code needs to keep track of a cost estimate for each # port in the bridge. Instead of a hack based on device name, try # and use ethtool to get port speed from device. This has been tested # on e100 (uses ethtool_ops) and e1000 (does ethtool the hard way) # and dummy (no ethtool). # # Need to export dev_ethtool() to allow bridge module to get to # it easily. # # Code takes care to maintain same locking and semantics as if ioctl # was being done from application. # # net/core/ethtool.c # 2004/04/16 14:14:28-07:00 shemminger@osdl.org +1 -0 # [BRIDGE]: Use ethtool to get port speed. # # The bridge code needs to keep track of a cost estimate for each # port in the bridge. Instead of a hack based on device name, try # and use ethtool to get port speed from device. This has been tested # on e100 (uses ethtool_ops) and e1000 (does ethtool the hard way) # and dummy (no ethtool). # # Need to export dev_ethtool() to allow bridge module to get to # it easily. # # Code takes care to maintain same locking and semantics as if ioctl # was being done from application. # # net/bridge/br_ioctl.c # 2004/04/16 14:14:28-07:00 shemminger@osdl.org +0 -2 # [BRIDGE]: Use ethtool to get port speed. # # The bridge code needs to keep track of a cost estimate for each # port in the bridge. Instead of a hack based on device name, try # and use ethtool to get port speed from device. This has been tested # on e100 (uses ethtool_ops) and e1000 (does ethtool the hard way) # and dummy (no ethtool). # # Need to export dev_ethtool() to allow bridge module to get to # it easily. # # Code takes care to maintain same locking and semantics as if ioctl # was being done from application. # # net/bridge/br_if.c # 2004/04/16 14:14:28-07:00 shemminger@osdl.org +80 -30 # [BRIDGE]: Use ethtool to get port speed. # # The bridge code needs to keep track of a cost estimate for each # port in the bridge. Instead of a hack based on device name, try # and use ethtool to get port speed from device. This has been tested # on e100 (uses ethtool_ops) and e1000 (does ethtool the hard way) # and dummy (no ethtool). # # Need to export dev_ethtool() to allow bridge module to get to # it easily. # # Code takes care to maintain same locking and semantics as if ioctl # was being done from application. # # ChangeSet # 2004/04/16 14:13:29-07:00 shemminger@osdl.org # [BRIDGE]: Make use of jiffies_to_clock. # # net/bridge/br_ioctl.c # 2004/04/16 14:13:16-07:00 shemminger@osdl.org +11 -22 # [BRIDGE]: Make use of jiffies_to_clock. # # net/bridge/br_fdb.c # 2004/04/16 14:13:16-07:00 shemminger@osdl.org +2 -1 # [BRIDGE]: Make use of jiffies_to_clock. # # ChangeSet # 2004/04/16 14:12:55-07:00 shemminger@osdl.org # [BRIDGE]: Fix rmmod race. # # Fix observed race between removing bridge module and ip packets # in flight. Need to remove the hook last, after all bridges are gone # not the other way around. # # net/bridge/br.c # 2004/04/16 14:12:43-07:00 shemminger@osdl.org +5 -4 # [BRIDGE]: Fix rmmod race. # # Fix observed race between removing bridge module and ip packets # in flight. Need to remove the hook last, after all bridges are gone # not the other way around. # # ChangeSet # 2004/04/16 14:11:59-07:00 shemminger@osdl.org # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_stp_timer.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_stp_if.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_stp_bpdu.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_stp.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_notify.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_ioctl.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_input.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +0 -1 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_if.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -3 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_forward.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +0 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br_device.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +0 -1 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # net/bridge/br.c # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +1 -2 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # include/linux/if_bridge.h # 2004/04/16 14:11:46-07:00 shemminger@osdl.org +0 -3 # [BRIDGE]: Include file cleanup. # # Cleanup some of the include file's in the bridge code. # * if_bridge.h defines net_bridge, but not needed as part of the API. # * get rid of places that include if_bridge.h and uaccess.h but don't # actually do API work. # # ChangeSet # 2004/04/16 22:09:02+01:00 rmk@flint.arm.linux.org.uk # [ARM] Add __user address space identifiers for sparse. # # include/asm-arm/uaccess.h # 2004/04/16 22:07:01+01:00 rmk@flint.arm.linux.org.uk +15 -15 # Add __user address space identifiers for sparse. # # arch/arm/mm/alignment.c # 2004/04/16 22:07:00+01:00 rmk@flint.arm.linux.org.uk +2 -2 # Add __user address space identifiers for sparse. # # arch/arm/kernel/sys_arm.c # 2004/04/16 22:07:00+01:00 rmk@flint.arm.linux.org.uk +22 -20 # Add __user address space identifiers for sparse. # # arch/arm/kernel/signal.c # 2004/04/16 22:07:00+01:00 rmk@flint.arm.linux.org.uk +16 -16 # Add __user address space identifiers for sparse. # # arch/arm/kernel/ptrace.c # 2004/04/16 22:07:00+01:00 rmk@flint.arm.linux.org.uk +10 -10 # Add __user address space identifiers for sparse. # # ChangeSet # 2004/04/16 22:02:08+01:00 rmk@flint.arm.linux.org.uk # [ARM] Update mach-types file. # # arch/arm/tools/mach-types # 2004/04/16 21:56:48+01:00 rmk@flint.arm.linux.org.uk +41 -3 # Update mach-types. # # ChangeSet # 2004/04/16 13:56:23-07:00 arjanv@redhat.com # [NET]: Add some sparse annotations to network driver stack. # # net/core/ethtool.c # 2004/04/16 13:56:11-07:00 arjanv@redhat.com +30 -30 # [NET]: Add some sparse annotations to network driver stack. # # net/core/dv.c # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +1 -1 # [NET]: Add some sparse annotations to network driver stack. # # net/core/dev.c # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +5 -5 # [NET]: Add some sparse annotations to network driver stack. # # include/linux/wireless.h # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +1 -1 # [NET]: Add some sparse annotations to network driver stack. # # include/linux/if.h # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +1 -1 # [NET]: Add some sparse annotations to network driver stack. # # include/linux/divert.h # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +2 -2 # [NET]: Add some sparse annotations to network driver stack. # # drivers/net/b44.c # 2004/04/16 13:56:10-07:00 arjanv@redhat.com +3 -3 # [NET]: Add some sparse annotations to network driver stack. # # ChangeSet # 2004/04/16 13:55:01-07:00 ak@suse.de # [IPV6]: Limit network triggerable printks. # # net/ipv6/udp.c # 2004/04/16 13:54:44-07:00 ak@suse.de +4 -4 # [IPV6]: Limit network triggerable printks. # # net/ipv6/tcp_ipv6.c # 2004/04/16 13:54:44-07:00 ak@suse.de +1 -1 # [IPV6]: Limit network triggerable printks. # # net/ipv6/raw.c # 2004/04/16 13:54:44-07:00 ak@suse.de +2 -1 # [IPV6]: Limit network triggerable printks. # # net/ipv6/ip6_output.c # 2004/04/16 13:54:44-07:00 ak@suse.de +2 -2 # [IPV6]: Limit network triggerable printks. # # net/ipv6/icmp.c # 2004/04/16 13:54:44-07:00 ak@suse.de +12 -12 # [IPV6]: Limit network triggerable printks. # # net/ipv6/exthdrs.c # 2004/04/16 13:54:43-07:00 ak@suse.de +4 -4 # [IPV6]: Limit network triggerable printks. # # net/ipv6/esp6.c # 2004/04/16 13:54:43-07:00 ak@suse.de +2 -2 # [IPV6]: Limit network triggerable printks. # # net/ipv6/datagram.c # 2004/04/16 13:54:43-07:00 ak@suse.de +2 -2 # [IPV6]: Limit network triggerable printks. # # net/ipv6/ah6.c # 2004/04/16 13:54:43-07:00 ak@suse.de +10 -10 # [IPV6]: Limit network triggerable printks. # # net/ipv4/ipcomp.c # 2004/04/16 13:54:43-07:00 ak@suse.de +2 -2 # [IPV6]: Limit network triggerable printks. # # net/ipv4/icmp.c # 2004/04/16 13:54:43-07:00 ak@suse.de +4 -4 # [IPV6]: Limit network triggerable printks. # # net/ipv4/esp4.c # 2004/04/16 13:54:43-07:00 ak@suse.de +4 -4 # [IPV6]: Limit network triggerable printks. # # include/net/sock.h # 2004/04/16 13:54:43-07:00 ak@suse.de +2 -0 # [IPV6]: Limit network triggerable printks. # # ChangeSet # 2004/04/16 21:54:40+01:00 rmk@flint.arm.linux.org.uk # [ARM] Remove needless export of __do_softirq() # # arch/arm/kernel/armksyms.c # 2004/04/16 21:52:51+01:00 rmk@flint.arm.linux.org.uk +0 -3 # No need to export __do_softirq() now. # # ChangeSet # 2004/04/16 13:49:08-07:00 ak@suse.de # [NET]: Do lazy gettimeofday for network packets. # # net/x25/af_x25.c # 2004/04/16 13:48:55-07:00 ak@suse.de +3 -7 # [NET]: Do lazy gettimeofday for network packets. # # net/wanrouter/af_wanpipe.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -7 # [NET]: Do lazy gettimeofday for network packets. # # net/sunrpc/svcsock.c # 2004/04/16 13:48:55-07:00 ak@suse.de +6 -0 # [NET]: Do lazy gettimeofday for network packets. # # net/sctp/input.c # 2004/04/16 13:48:55-07:00 ak@suse.de +6 -0 # [NET]: Do lazy gettimeofday for network packets. # # net/rxrpc/transport.c # 2004/04/16 13:48:55-07:00 ak@suse.de +5 -0 # [NET]: Do lazy gettimeofday for network packets. # # net/rose/af_rose.c # 2004/04/16 13:48:55-07:00 ak@suse.de +2 -6 # [NET]: Do lazy gettimeofday for network packets. # # net/packet/af_packet.c # 2004/04/16 13:48:55-07:00 ak@suse.de +6 -7 # [NET]: Do lazy gettimeofday for network packets. # # net/netrom/af_netrom.c # 2004/04/16 13:48:55-07:00 ak@suse.de +4 -10 # [NET]: Do lazy gettimeofday for network packets. # # net/irda/af_irda.c # 2004/04/16 13:48:55-07:00 ak@suse.de +2 -8 # [NET]: Do lazy gettimeofday for network packets. # # net/ipx/af_ipx.c # 2004/04/16 13:48:55-07:00 ak@suse.de +4 -10 # [NET]: Do lazy gettimeofday for network packets. # # net/ipv6/ndisc.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -1 # [NET]: Do lazy gettimeofday for network packets. # # net/ipv6/af_inet6.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -7 # [NET]: Do lazy gettimeofday for network packets. # # net/ipv4/arp.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -1 # [NET]: Do lazy gettimeofday for network packets. # # net/ipv4/af_inet.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -5 # [NET]: Do lazy gettimeofday for network packets. # # net/econet/af_econet.c # 2004/04/16 13:48:55-07:00 ak@suse.de +2 -4 # [NET]: Do lazy gettimeofday for network packets. # # net/core/sock.c # 2004/04/16 13:48:55-07:00 ak@suse.de +41 -1 # [NET]: Do lazy gettimeofday for network packets. # # net/core/neighbour.c # 2004/04/16 13:48:55-07:00 ak@suse.de +1 -1 # [NET]: Do lazy gettimeofday for network packets. # # net/core/dev.c # 2004/04/16 13:48:55-07:00 ak@suse.de +4 -4 # [NET]: Do lazy gettimeofday for network packets. # # net/ax25/af_ax25.c # 2004/04/16 13:48:54-07:00 ak@suse.de +1 -6 # [NET]: Do lazy gettimeofday for network packets. # # net/atm/ioctl.c # 2004/04/16 13:48:54-07:00 ak@suse.de +2 -6 # [NET]: Do lazy gettimeofday for network packets. # # net/appletalk/ddp.c # 2004/04/16 13:48:54-07:00 ak@suse.de +1 -7 # [NET]: Do lazy gettimeofday for network packets. # # include/net/sock.h # 2004/04/16 13:48:54-07:00 ak@suse.de +28 -5 # [NET]: Do lazy gettimeofday for network packets. # # include/net/neighbour.h # 2004/04/16 13:48:54-07:00 ak@suse.de +2 -0 # [NET]: Do lazy gettimeofday for network packets. # # ChangeSet # 2004/04/16 11:36:57-07:00 davem@nuts.davemloft.net # Merge # # net/ipv4/netfilter/ip_conntrack_tftp.c # 2004/04/16 11:36:54-07:00 davem@nuts.davemloft.net +0 -0 # SCCS merged # # net/ipv4/netfilter/ipt_ULOG.c # 2004/04/16 11:35:36-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # net/ipv4/netfilter/ip_conntrack_irc.c # 2004/04/16 11:35:35-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/netfilter_ipv4/ip_conntrack.h # 2004/04/16 11:35:35-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/04/16 10:37:13-07:00 davem@nuts.davemloft.net # Merge. # # drivers/usb/gadget/ether.c # 2004/04/16 10:37:01-07:00 davem@nuts.davemloft.net +1 -4 # Resolve conflict with shemminger's random_ether_addr() changes. # # ChangeSet # 2004/04/16 13:01:59-04:00 brazilnut@us.ibm.com # [PATCH] pcnet32 transmit performance fix # # When the pcnet32 adapter is installed in a system with long PCI latency # and the read burst bit is not set, performance on transmission is very # low (under 20Mbit on a 100Mbit link). This patch against 2.6.6-rc1 will # make sure that read and write bursts are enabled. Tested on ppc64 and # ia32. # # drivers/net/pcnet32.c # 2004/04/15 07:47:00-04:00 brazilnut@us.ibm.com +2 -1 # pcnet32 transmit performance fix # # ChangeSet # 2004/04/16 13:01:32-04:00 jgarzik@redhat.com # [netdrvr via-rhine] Fix MII phy scanning # # Noticed by Roger Luethi, via-rhine maintainer. # # drivers/net/via-rhine.c # 2004/04/16 13:01:27-04:00 jgarzik@redhat.com +22 -20 # [netdrvr via-rhine] Fix MII phy scanning # # Noticed by Roger Luethi, via-rhine maintainer. # # ChangeSet # 2004/04/16 12:59:08-04:00 akpm@osdl.org # [PATCH] amd8111e retval fix # # drivers/net/amd8111e.c: In function `amd8111e_vlan_rx': # drivers/net/amd8111e.c:677: warning: control reaches end of non-void function # # drivers/net/amd8111e.c # 2004/04/15 12:35:34-04:00 akpm@osdl.org +1 -1 # amd8111e retval fix # # ChangeSet # 2004/04/16 12:55:41-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/netdev-2.6/misc # into redhat.com:/spare/repo/net-drivers-2.6 # # include/linux/netdevice.h # 2004/04/16 12:55:38-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/16 12:55:38-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # MAINTAINERS # 2004/04/16 12:55:38-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # net/netlink/af_netlink.c # 2004/04/16 09:24:35-07:00 davem@nuts.davemloft.net +0 -94 # Auto merged # # include/linux/netlink.h # 2004/04/16 09:24:35-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # drivers/usb/net/usbnet.c # 2004/04/16 09:24:35-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # drivers/net/Kconfig # 2004/04/16 09:24:35-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # arch/ppc64/kernel/prom.c # 2004/04/16 09:00:53-07:00 anton@samba.org +5 -0 # ppc64: always initialise dn->type and dn->name # # arch/ppc64/kernel/rtas.c # 2004/04/16 08:38:11-07:00 benh@kernel.crashing.org +51 -28 # ppc64: Fix RTAS races on pSeries # # arch/ppc64/kernel/entry.S # 2004/04/16 08:06:53-07:00 benh@kernel.crashing.org +15 -2 # ppc64: Fix RTAS races on pSeries # # ChangeSet # 2004/04/16 15:27:18+01:00 rmk@flint.arm.linux.org.uk # [ARM] Add --no-undefined to linker command line. # # Many binutils versions over the last year appear to silently build # assembler files with undefined constants, and able to successfully # create executables from such files. The assembler appears to add # undefined symbols to the symbol table without any corresponding # relocation information. Obviously this is bad news since the # resulting executable may not be what the programmer intended. # Work around the problem by forcing the linker to fail if there are # any undefined symbols in the final object(s). # # arch/arm/boot/compressed/Makefile # 2004/04/16 15:25:13+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Add --no-undefined to linker command line # # arch/arm/Makefile # 2004/04/16 15:25:13+01:00 rmk@flint.arm.linux.org.uk +1 -1 # Add --no-undefined to linker command line. # # ChangeSet # 2004/04/16 06:55:37-07:00 benh@kernel.crashing.org # [PATCH] ppc64: Fix RTAS races on pSeries # # The low level kernel interface to RTAS (the firmware runtime services) # was plagued with races that could cause from bogus results of RTAS # operations to total machine crashes in some circumstances. This patch # fix the ones I could identify, hoping I didn't miss any. I also added # a WARN_ON (well, it's asm equivalent) to enter_rtas to make sure we # never _ever_ try to call that with interrupts enabled. # # ChangeSet # 2004/04/16 06:53:12-07:00 anton@samba.org # [PATCH] ppc64: always initialise dn->type and dn->name # # This fix comes from ppc32. Always initialise dn->type and dn->name so # that code doesnt have to check for NULL everywhere. There is at least # one bug report where we oopsed because of this. # # ChangeSet # 2004/04/16 06:52:58-07:00 anton@samba.org # [PATCH] ppc64: catch branch to 0 in real mode # # We have been debugging some strange fails where we branch to 0 in real # mode. At the moment this results in the cpu running through the # initialisation code and failing somewhere well into it. # # The following patch uses the featuring nop'ing code to remove the branch # at real address 0 so it falls through to a trap instruction and gets # caught early. # # arch/ppc64/kernel/head.S # 2004/04/15 20:30:40-07:00 anton@samba.org +5 -0 # ppc64: catch branch to 0 in real mode # # ChangeSet # 2004/04/16 06:44:35-07:00 adam@evdebs.org # [PATCH] NMI watchdog Pentium M support # # This adda nmi_watchdog=2 support to the Pentium M processor. The P-M is # a P6 chip, but it shares some chipset logic with the Pentium 4, so it # requires this workaround to function. # # Without this patch, NMI gets stuck after 1 count. With it, the NMI # fires and breaks me out of UHCI-related hard lockups. # # This patch is basically a modified version of the same patch for # oprofile. See the threaded discussion here: # # http://lkml.org/lkml/2004/2/12/181 # # arch/i386/kernel/nmi.c # 2004/04/13 16:04:21-07:00 adam@evdebs.org +7 -0 # NMI watchdog Pentium M support # # ChangeSet # 2004/04/15 23:55:02-07:00 davem@nuts.davemloft.net # [IXGB]: ixgb.h needs dma-mapping.h # # drivers/net/ixgb/ixgb.h # 2004/04/15 23:54:46-07:00 davem@nuts.davemloft.net +1 -0 # [IXGB]: ixgb.h needs dma-mapping.h # # ChangeSet # 2004/04/15 23:54:31-07:00 davem@nuts.davemloft.net # [E1000]: e1000.h needs dma-mapping.h # # drivers/net/e1000/e1000.h # 2004/04/15 23:54:06-07:00 davem@nuts.davemloft.net +1 -0 # [E1000]: e1000.h needs dma-mapping.h # # ChangeSet # 2004/04/15 11:57:06-07:00 geert@linux-m68k.org # [PATCH] Amiga Zorro8390 Ethernet section conflict # # Jeff Garzik notes that the previous cleanup highlights a bug: # > # > static const struct card_info { # > zorro_id id; # > const char *name; # > unsigned int offset; # > } cards[] __initdata = { # > # > and the lone user is __devinit: # > # > static int __devinit zorro8390_init_one(struct zorro_dev *z, # > const struct zorro_device_id *ent) # # Here's the fix.. # # drivers/net/zorro8390.c # 2004/04/15 11:28:54-07:00 geert@linux-m68k.org +1 -1 # Amiga Zorro8390 Ethernet section conflict # # ChangeSet # 2004/04/15 11:56:52-07:00 James.Bottomley@SteelEye.com # [PATCH] fix non-PC subarchs which were broken by i386 probe_roms change # # The author apparently didn't understand that only the mach-default # include directory is included by fallback for header files only. You # can't stick a .c file in mach-default and expect all subarchs to be able # to use it. # # The correct fix is to put std_resources.c in the kernel directory and # give it its own Kconfig symbol for conditional compile so that subarchs # may choose to include it or not. # # arch/i386/mach-default/Makefile # 2004/04/15 06:25:23-07:00 James.Bottomley@SteelEye.com +1 -1 # fix non-PC subarchs which were broken by i386 probe_roms change # # arch/i386/kernel/std_resources.c # 2004/04/15 06:25:23-07:00 James.Bottomley@SteelEye.com +0 -0 # fix non-PC subarchs which were broken by i386 probe_roms change # # arch/i386/kernel/Makefile # 2004/04/15 06:25:23-07:00 James.Bottomley@SteelEye.com +1 -0 # fix non-PC subarchs which were broken by i386 probe_roms change # # arch/i386/Kconfig # 2004/04/15 06:25:23-07:00 James.Bottomley@SteelEye.com +6 -0 # fix non-PC subarchs which were broken by i386 probe_roms change # # ChangeSet # 2004/04/15 10:29:23-07:00 xschmi00@stud.feec.vutbr.cz # [PATCH] USB: Fix vicam debug compile, fix user access # # The last copy_from_user patch to the vicam driver broke compilation with # VICAM_DEBUG on. # # There is also another copy_from_user missing in case VIDIOCSPICT. # # This fixes both issues. # # drivers/usb/media/vicam.c # 2004/04/15 02:50:03-07:00 xschmi00@stud.feec.vutbr.cz +13 -8 # USB: Fix vicam debug compile, fix user access # # arch/ppc64/configs/g5_defconfig # 2004/04/15 10:15:11-07:00 benh@kernel.crashing.org +18 -8 # ppc64: update g5_defconfig # # ChangeSet # 2004/04/15 09:20:00-07:00 James.Bottomley@SteelEye.com # [PATCH] fix 4k irqstacks on x86 (and add voyager support) # # There's a bug in the x86 code in that it sets the boot CPU to zero. # # This isn't correct since some subarch's use physically indexed CPUs. # However, subarchs have either set the boot cpu before irq_INIT() (or # just inherited the default zero from INIT_THREAD_INFO()), so it's safe # to believe current_thread_info()->cpu about the boot cpu. # # arch/i386/mach-voyager/voyager_thread.c # 2004/04/15 02:11:35-07:00 James.Bottomley@SteelEye.com +1 -1 # fix 4k irqstacks on x86 (and add voyager support) # # arch/i386/mach-voyager/voyager_smp.c # 2004/04/15 02:52:49-07:00 James.Bottomley@SteelEye.com +4 -6 # fix 4k irqstacks on x86 (and add voyager support) # # arch/i386/kernel/i8259.c # 2004/04/15 02:59:27-07:00 James.Bottomley@SteelEye.com +1 -2 # fix 4k irqstacks on x86 (and add voyager support) # # ChangeSet # 2004/04/15 08:39:55-07:00 greg@kroah.com # Merge kroah.com:/home/greg/linux/BK/bleed-2.6 # into kroah.com:/home/greg/linux/BK/driver-2.6 # # drivers/video/fbmem.c # 2004/04/15 08:39:25-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/isdn/capi/capi.c # 2004/04/15 08:39:25-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/char/vt.c # 2004/04/15 08:39:24-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/char/tpqic02.c # 2004/04/15 08:39:24-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/char/istallion.c # 2004/04/15 08:39:24-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/04/15 08:22:54-07:00 greg@kroah.com # merge # # drivers/pci/hotplug/pciehp_hpc.c # 2004/04/15 08:22:38-07:00 greg@kroah.com +0 -1 # merge # # include/linux/pci_ids.h # 2004/04/15 08:18:12-07:00 greg@kroah.com +0 -0 # Auto merged # # include/linux/pci.h # 2004/04/15 08:18:12-07:00 greg@kroah.com +0 -0 # Auto merged # # drivers/net/e1000/e1000_main.c # 2004/04/15 08:18:12-07:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/04/15 07:04:22-07:00 benh@kernel.crashing.org # [PATCH] ppc64: update g5_defconfig # # This adds IOMMU support & IOMU virtual merging to the default g5 config. # # This will not impair performances of machines that don't need the iommu # (the kernel will only enable it if you have more than 2Gb of RAM, though # you can explicitely enable it using a command line argument). # # ChangeSet # 2004/04/15 07:04:10-07:00 benh@kernel.crashing.org # [PATCH] ppc64: Fix possible duplicate MMU hash entries # # The current code has a subtle race where 2 hash PTEs can be inserted # for the same virtual address for a short period of time. There should # not be a stale one as the "old" one ultimately gets flushed, but the # architecture specifies that having two hash PTE is illegal and can # result in undefined behaviour. # # This patch fixes it by never clearing the _PAGE_HASHPTE bit when # doing test_and_clear_{young,dirty}. That means that subsequent faults # on those pages will have a bit more overhead to "discover" that the # hash entry was indeed evicted. # # It also adds a small optisation to avoid doing the atomic operation # and the hash flush in test_and_clear_dirty when the page isn't dirty # or when setting write protect while it's already set. # # include/asm-ppc64/pgtable.h # 2004/04/08 10:30:57-07:00 benh@kernel.crashing.org +9 -26 # ppc64: Fix possible duplicate MMU hash entries # # ChangeSet # 2004/04/15 07:03:54-07:00 akpm@osdl.org # [PATCH] posix messages queues for s390. # # From: Martin Schwidefsky # # The new message queue interface needs the following patch to get it working # on s390 (31-bit, 64-bit and 31-bit compat). # # include/asm-s390/unistd.h # 2004/04/14 18:37:53-07:00 akpm@osdl.org +13 -8 # posix messages queues for s390. # # arch/s390/kernel/syscalls.S # 2004/04/14 18:37:53-07:00 akpm@osdl.org +10 -0 # posix messages queues for s390. # # arch/s390/kernel/compat_wrapper.S # 2004/04/14 18:37:53-07:00 akpm@osdl.org +44 -0 # posix messages queues for s390. # # ChangeSet # 2004/04/15 07:03:43-07:00 akpm@osdl.org # [PATCH] light-weight auditing framework for s390. # # From: Martin Schwidefsky # # This patch adds the TIF_SYSCALL_AUDIT option to the s390 ptrace interface. # # include/asm-s390/thread_info.h # 2004/04/14 18:37:53-07:00 akpm@osdl.org +2 -0 # light-weight auditing framework for s390. # # arch/s390/kernel/ptrace.c # 2004/04/14 18:37:53-07:00 akpm@osdl.org +9 -1 # light-weight auditing framework for s390. # # arch/s390/kernel/entry64.S # 2004/04/14 18:37:53-07:00 akpm@osdl.org +12 -4 # light-weight auditing framework for s390. # # arch/s390/kernel/entry.S # 2004/04/14 18:37:53-07:00 akpm@osdl.org +12 -4 # light-weight auditing framework for s390. # # ChangeSet # 2004/04/15 07:03:32-07:00 akpm@osdl.org # [PATCH] Add mqueue support to x86-64 # # From: Andi Kleen # # Add POSIX mqueue support to x86-64. # # include/asm-x86_64/unistd.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +21 -3 # Add mqueue support to x86-64 # # include/asm-x86_64/ia32_unistd.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +11 -1 # Add mqueue support to x86-64 # # arch/x86_64/ia32/ia32entry.S # 2004/04/14 18:37:52-07:00 akpm@osdl.org +10 -0 # Add mqueue support to x86-64 # # ChangeSet # 2004/04/15 07:03:20-07:00 akpm@osdl.org # [PATCH] ext3: journalled quotas # # From: Jan Kara # # Journalled quota support for ext3: The patch consists of two parts - ext3 # changes and changes in generic quota code. The main idea of the changes is # that a transaction is always started before any operation which changes quota # file and dirtifying of the quota causes its write to disk. These two changes # assure that quota change is journalled into the same transaction as the file # change and hence after journal replay quota is consistent with the filesystem # state. As during journal replay inodes from orphan list are deleted/truncated # we have to do quota_on before the replay of the orphan list - this problem is # solved by additional mount options to ext3 with quota file names and format. # # Some changes in generic code were also needed to assure that quota structure # in file is always allocated and so ordinary quota operations (like # adding/deleting a block/inode) need only a few blocks from the transaction. # # include/linux/quotaops.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +28 -7 # ext3: journalled quotas # # include/linux/quota.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +26 -27 # ext3: journalled quotas # # include/linux/ext3_jbd.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +16 -2 # ext3: journalled quotas # # include/linux/ext3_fs_sb.h # 2004/04/14 18:37:52-07:00 akpm@osdl.org +4 -0 # ext3: journalled quotas # # fs/stat.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +2 -0 # ext3: journalled quotas # # fs/quota_v2.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +41 -31 # ext3: journalled quotas # # fs/quota_v1.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +1 -6 # ext3: journalled quotas # # fs/ext3/super.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +297 -60 # ext3: journalled quotas # # fs/ext3/namei.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +18 -8 # ext3: journalled quotas # # fs/ext3/inode.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +23 -2 # ext3: journalled quotas # # fs/dquot.c # 2004/04/14 18:37:52-07:00 akpm@osdl.org +305 -114 # ext3: journalled quotas # # fs/Kconfig # 2004/04/14 18:37:52-07:00 akpm@osdl.org +7 -4 # ext3: journalled quotas # # ChangeSet # 2004/04/15 07:03:05-07:00 akpm@osdl.org # [PATCH] mq_open() and close_on_exec # # From: Chris Wright # # SUSv3 doesn't seem to specify one way or the other. I don't have the POSIX # specs, and the old docs I have suggest that mq_open() creates an object # which is to be closed upon exec. # # Jakub said: # # I think it is valid and required: # # http://www.opengroup.org/onlinepubs/007904975/functions/exec.html # # All open message queue descriptors in the calling process shall be # closed, as described in mq_close() # # I'll add a new test for this into glibc testsuite. # # ipc/mqueue.c # 2004/04/14 18:37:51-07:00 akpm@osdl.org +1 -0 # mq_open() and close_on_exec # # ChangeSet # 2004/04/15 07:02:51-07:00 akpm@osdl.org # [PATCH] radix-tree comment fix # # Fix various bogons and outright lies. # # mm/filemap.c # 2004/04/14 18:37:51-07:00 akpm@osdl.org +1 -1 # radix-tree comment fix # # lib/radix-tree.c # 2004/04/14 18:37:51-07:00 akpm@osdl.org +1 -6 # radix-tree comment fix # # include/linux/fs.h # 2004/04/14 18:37:51-07:00 akpm@osdl.org +1 -1 # radix-tree comment fix # # ChangeSet # 2004/04/15 07:02:37-07:00 akpm@osdl.org # [PATCH] Fix mq_notify with SIGEV_NONE notification # # From: Jakub Jelinek # # mq_notify (q, NULL) # # and # struct sigevent ev = { .sigev_notify = SIGEV_NONE }; # mq_notify (q, &ev) # # are not the same thing in POSIX, yet the kernel treats them the same. Only # the former makes the notification available to other processes immediately, # see # # http://www.opengroup.org/onlinepubs/007904975/functions/mq_notify.html # # Without the patch below, # # http://sources.redhat.com/ml/libc-hacker/2004-04/msg00028.html # # glibc test fails. # # I looked at mq in Solaris and they behave the same in this regard as Linux # with this patch. Kernel with this patch passes both Intel POSIX testsuite # (with testsuite fixes from Ulrich) and glibc mq testsuite. # # ipc/mqueue.c # 2004/04/14 18:44:20-07:00 akpm@osdl.org +46 -47 # Fix mq_notify with SIGEV_NONE notification # # ChangeSet # 2004/04/14 22:34:22-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/linux-2.6 # into redhat.com:/spare/repo/misc-2.6 # # MAINTAINERS # 2004/04/14 22:34:18-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/14 21:04:48-04:00 jgarzik@redhat.com # [libata sata_promise] fix taskfile delivery cases # # We should only be touching the ATA shadow registers if we are doing # PIO. # # drivers/scsi/sata_promise.c # 2004/04/14 17:04:43-04:00 jgarzik@redhat.com +2 -2 # [libata sata_promise] fix taskfile delivery cases # # We should only be touching the ATA shadow registers if we are doing # PIO. # # ChangeSet # 2004/04/14 21:04:35-04:00 jgarzik@redhat.com # [libata] move some PIO state init to its proper place # # drivers/scsi/libata-scsi.c # 2004/04/14 17:04:29-04:00 jgarzik@redhat.com +0 -1 # [libata] move some PIO state init to its proper place # # drivers/scsi/libata-core.c # 2004/04/14 17:04:29-04:00 jgarzik@redhat.com +1 -0 # [libata] move some PIO state init to its proper place # # ChangeSet # 2004/04/14 21:03:15-04:00 jgarzik@redhat.com # [libata] abstract SCSI->ATA translation a bit # # drivers/scsi/libata-scsi.c # 2004/04/14 17:01:33-04:00 jgarzik@redhat.com +16 -10 # [libata] abstract SCSI->ATA translation a bit # # ChangeSet # 2004/04/13 14:12:12-04:00 p_gortmaker@yahoo.com # [netdrvr 8390] Fix 8390 log spam # # It seems that PCMCIA 8390 users get spammed with a few annoying # messages upon card removal. I guess 8390 could be taught to better # detect and deal with these things, but here is a quick fix. # # drivers/net/8390.c # 2004/04/13 14:12:07-04:00 p_gortmaker@yahoo.com +1 -1 # [netdrvr 8390] Fix 8390 log spam # # It seems that PCMCIA 8390 users get spammed with a few annoying # messages upon card removal. I guess 8390 could be taught to better # detect and deal with these things, but here is a quick fix. # # ChangeSet # 2004/04/13 14:07:53-04:00 mpm@selenic.com # [PATCH] netpoll transmit busy bugfix # # Fix for handling of full transmit queue when netpoll trap is enabled. # # From Stelian Pop # # net/core/netpoll.c # 2004/04/10 16:19:31-04:00 mpm@selenic.com +3 -9 # netpoll transmit busy bugfix # # ChangeSet # 2004/04/13 14:07:45-04:00 mpm@selenic.com # [PATCH] netpoll early ARP handling # # Handle ARP requests while device is trapped before in_dev is # initialized using netpoll config. Allows early kgdboe usage. # # From Stelian Pop # # net/core/netpoll.c # 2004/04/10 16:15:25-04:00 mpm@selenic.com +6 -13 # netpoll early ARP handling # # ChangeSet # 2004/04/13 14:07:24-04:00 rmk@arm.linux.org.uk # [PATCH] etherh updates # # Update Acorn EtherH driver - convert to use mmio instead of emulated # PIO. Convert card-specific parameters to a data structure rather # than code-based selected. # # Please review and submit upstream. Thanks. # # drivers/net/arm/etherh.c # 2004/04/04 12:59:31-04:00 rmk@arm.linux.org.uk +170 -148 # etherh updates # # drivers/net/8390.h # 2004/04/04 10:59:53-04:00 rmk@arm.linux.org.uk +13 -2 # etherh updates # # ChangeSet # 2004/04/13 14:07:12-04:00 akpm@osdl.org # [PATCH] sk_mca multicast fix # # Spotted by Jean Delvare : it has its memset arguments the # wrong way round. # # drivers/net/sk_mca.c # 2004/04/10 04:57:20-04:00 akpm@osdl.org +2 -2 # sk_mca multicast fix # # ChangeSet # 2004/04/12 21:46:19-07:00 davem@nuts.davemloft.net # [SPARC64]: Disable -Werror for a bit. # # arch/sparc64/kernel/Makefile # 2004/04/12 21:45:57-07:00 davem@nuts.davemloft.net +1 -1 # [SPARC64]: Disable -Werror for a bit. # # ChangeSet # 2004/04/12 19:30:08-07:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/sparcwork-2.6 # into nuts.davemloft.net:/disk1/BK/sparc-2.6 # # kernel/sysctl.c # 2004/04/12 19:30:00-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/sysctl.h # 2004/04/12 19:30:00-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # arch/sparc64/mm/hugetlbpage.c # 2004/04/12 19:30:00-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # arch/sparc/kernel/process.c # 2004/04/12 19:30:00-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/04/12 16:57:12-07:00 lxiep@us.ibm.com # [PATCH] PCI Hotplug: php_phy_location.patch # # Adds a file to show the pci hotplug slot location for the ppc64 driver # only. # # drivers/pci/hotplug/rpaphp_slot.c # 2004/04/11 12:11:18-07:00 lxiep@us.ibm.com +42 -38 # PCI Hotplug: php_phy_location.patch # # drivers/pci/hotplug/rpaphp_core.c # 2004/04/11 12:11:18-07:00 lxiep@us.ibm.com +7 -16 # PCI Hotplug: php_phy_location.patch # # drivers/pci/hotplug/rpaphp.h # 2004/04/11 12:11:18-07:00 lxiep@us.ibm.com +2 -0 # PCI Hotplug: php_phy_location.patch # # drivers/pci/hotplug/rpadlpar_core.c # 2004/04/11 12:11:18-07:00 lxiep@us.ibm.com +8 -15 # PCI Hotplug: php_phy_location.patch # # ChangeSet # 2004/04/12 16:46:07-07:00 marcel@holtmann.org # [PATCH] Fix sysfs class support for CAPI # # this patch fixes a bug in the CAPI TTY support, because the ->name value # of the TTY driver shouldn't contain a "/". After changing this there are # now a "capi20" TTY device and a "capi20" control device and so I renamed # the control device to "capi". The userspace visible part must be done by # udev and I added these two rules to restore the old namespace: # # # CAPI devices # KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" # KERNEL="capi*", NAME="capi/%n" # # drivers/isdn/capi/capi.c # 2004/04/10 15:06:20-07:00 marcel@holtmann.org +3 -2 # Fix sysfs class support for CAPI # # ChangeSet # 2004/04/11 17:39:07-07:00 davem@nuts.davemloft.net # [SPARC64]: Provide _mcount as well as mcount. # # arch/sparc64/lib/mcount.S # 2004/04/11 17:38:51-07:00 davem@nuts.davemloft.net +2 -1 # [SPARC64]: Provide _mcount as well as mcount. # # ChangeSet # 2004/04/11 14:16:46-07:00 jon@focalhost.com # [CRYPTO]: ARC4 Kconfig clarification. # # crypto/Kconfig # 2004/04/11 14:16:32-07:00 jon@focalhost.com +4 -3 # [CRYPTO]: ARC4 Kconfig clarification. # # ChangeSet # 2004/04/11 14:14:55-07:00 hadi@cyberus.ca # [NET_SCHED]: Check for NULL opt in dsmark_init. # # net/sched/sch_dsmark.c # 2004/04/11 14:14:37-07:00 hadi@cyberus.ca +2 -1 # [NET_SCHED]: Check for NULL opt in dsmark_init. # # ChangeSet # 2004/04/11 14:08:46-07:00 davem@nuts.davemloft.net # [SPARC64]: Control -fomit-frame-pointer using CONFIG_FRAME_POINTER. # # arch/sparc64/Makefile # 2004/04/11 14:08:29-07:00 davem@nuts.davemloft.net +0 -1 # [SPARC64]: Control -fomit-frame-pointer using CONFIG_FRAME_POINTER. # # arch/sparc64/Kconfig # 2004/04/11 14:08:29-07:00 davem@nuts.davemloft.net +5 -0 # [SPARC64]: Control -fomit-frame-pointer using CONFIG_FRAME_POINTER. # # ChangeSet # 2004/04/10 10:12:50-07:00 akpm@osdl.org # [NET]: Fix memset args in sk_mca, noticed by Jean Delvare # # drivers/net/sk_mca.c # 2004/04/10 10:12:37-07:00 akpm@osdl.org +2 -2 # [NET]: Fix memset args in sk_mca, noticed by Jean Delvare # # ChangeSet # 2004/04/09 23:51:52-07:00 akpm@osdl.org # [NET]: Fix printk warnings in strip driver. # # drivers/net/wireless/strip.c # 2004/04/09 23:51:29-07:00 akpm@osdl.org +1 -1 # [NET]: Fix printk warnings in strip driver. # # ChangeSet # 2004/04/09 23:45:53-07:00 akpm@osdl.org # [NET]: Fix printk warnings in wireless/strip.c # # drivers/net/wireless/strip.c # 2004/04/09 23:45:40-07:00 akpm@osdl.org +2 -2 # [NET]: Fix printk warnings in wireless/strip.c # # ChangeSet # 2004/04/09 23:43:58-07:00 akpm@osdl.org # [IRDA]: Fix 32-bit pointer bug in donauboe.c # # drivers/net/irda/donauboe.c # 2004/04/09 23:43:45-07:00 akpm@osdl.org +1 -1 # [IRDA]: Fix 32-bit pointer bug in donauboe.c # # ChangeSet # 2004/04/09 23:43:10-07:00 akpm@osdl.org # [IRDA]: Fix warnings in sir_dev.c # # drivers/net/irda/sir_dev.c # 2004/04/09 23:42:57-07:00 akpm@osdl.org +3 -2 # [IRDA]: Fix warnings in sir_dev.c # # ChangeSet # 2004/04/09 21:18:22-07:00 akpm@osdl.org # [ATM]: Fix printk warnings in ambassador driver. # # drivers/atm/ambassador.c # 2004/04/09 21:18:09-07:00 akpm@osdl.org +4 -4 # [ATM]: Fix printk warnings in ambassador driver. # # ChangeSet # 2004/04/09 21:17:39-07:00 akpm@osdl.org # [SCTP]: Fix printk warnings. # # net/sctp/socket.c # 2004/04/09 21:17:26-07:00 akpm@osdl.org +4 -4 # [SCTP]: Fix printk warnings. # # ChangeSet # 2004/04/09 21:16:29-07:00 shemminger@osdl.org # [NET]: Use random address in usbnet driver. # # drivers/usb/net/usbnet.c # 2004/04/09 21:16:16-07:00 shemminger@osdl.org +1 -3 # [NET]: Use random address in usbnet driver. # # ChangeSet # 2004/04/09 21:16:06-07:00 shemminger@osdl.org # [NET]: Use random address in usb gadget driver. # # drivers/usb/gadget/ether.c # 2004/04/09 21:15:53-07:00 shemminger@osdl.org +2 -6 # [NET]: Use random address in usb gadget driver. # # ChangeSet # 2004/04/09 21:15:42-07:00 shemminger@osdl.org # [NET]: Use random address in dummy driver. # # drivers/net/dummy.c # 2004/04/09 21:15:29-07:00 shemminger@osdl.org +15 -0 # [NET]: Use random address in dummy driver. # # ChangeSet # 2004/04/09 21:15:02-07:00 shemminger@osdl.org # [NET]: Add random_ether_addr to ether_device.h # # include/linux/etherdevice.h # 2004/04/09 21:14:49-07:00 shemminger@osdl.org +14 -0 # [NET]: Add random_ether_addr to ether_device.h # # ChangeSet # 2004/04/09 21:13:22-07:00 yoshfuji@linux-ipv6.org # [IPV6]: Mark MLDv2 report as known. # # Mark MLDv2 Report as known ICMPv6 type. # (We just ignore MLDv2 Reports on hosts as the spec says.) # # net/ipv6/icmp.c # 2004/04/09 21:13:09-07:00 yoshfuji@linux-ipv6.org +1 -0 # [IPV6]: Mark MLDv2 report as known. # # Mark MLDv2 Report as known ICMPv6 type. # (We just ignore MLDv2 Reports on hosts as the spec says.) # # ChangeSet # 2004/04/09 20:52:48-07:00 jt@bougret.hpl.hp.com # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/w83977af_ir.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +2 -2 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/vlsi_ir.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/nsc-ircc.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/irport.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/irda-usb.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/au1k_ir.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/ali-ircc.c # 2004/04/09 20:52:31-07:00 jt@bougret.hpl.hp.com +1 -1 # [IRDA]: Move IRDA device headers to more appropriate place. # # drivers/net/irda/w83977af_ir.h # 2004/04/09 20:51:15-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/w83977af_ir.h -> drivers/net/irda/w83977af_ir.h # # drivers/net/irda/w83977af.h # 2004/04/09 20:51:04-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/w83977af.h -> drivers/net/irda/w83977af.h # # drivers/net/irda/vlsi_ir.h # 2004/04/09 20:51:01-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/vlsi_ir.h -> drivers/net/irda/vlsi_ir.h # # drivers/net/irda/nsc-ircc.h # 2004/04/09 20:50:52-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/nsc-ircc.h -> drivers/net/irda/nsc-ircc.h # # drivers/net/irda/irport.h # 2004/04/09 20:50:44-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/irport.h -> drivers/net/irda/irport.h # # drivers/net/irda/irda-usb.h # 2004/04/09 20:49:17-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/irda-usb.h -> drivers/net/irda/irda-usb.h # # drivers/net/irda/au1000_ircc.h # 2004/04/09 20:49:12-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/au1000_ircc.h -> drivers/net/irda/au1000_ircc.h # # drivers/net/irda/ali-ircc.h # 2004/04/09 20:49:04-07:00 jt@bougret.hpl.hp.com +0 -0 # Rename: include/net/irda/ali-ircc.h -> drivers/net/irda/ali-ircc.h # # BitKeeper/deleted/.del-toshoboe.h~cf0f888518178705 # 2004/04/09 20:48:50-07:00 jt@bougret.hpl.hp.com +0 -0 # Delete: include/net/irda/toshoboe.h # # BitKeeper/deleted/.del-smc-ircc.h~60c06275794237d7 # 2004/04/09 20:48:45-07:00 jt@bougret.hpl.hp.com +0 -0 # Delete: include/net/irda/smc-ircc.h # # ChangeSet # 2004/04/09 16:37:48-07:00 chas@cmf.nrl.navy.mil # [ATM]: [nicstar] using dev_alloc_skb() (reported by Johnston, # # drivers/atm/nicstar.c # 2004/04/09 16:37:35-07:00 chas@cmf.nrl.navy.mil +20 -20 # [ATM]: [nicstar] using dev_alloc_skb() (reported by Johnston, # # ChangeSet # 2004/04/09 16:36:55-07:00 chas@cmf.nrl.navy.mil # [ATM]: get atm_guess_pdu2truesize() right # # include/linux/atmdev.h # 2004/04/09 16:36:42-07:00 chas@cmf.nrl.navy.mil +2 -2 # [ATM]: get atm_guess_pdu2truesize() right # # ChangeSet # 2004/04/09 16:34:52-07:00 laforge@netfilter.org # [NETFILTER]: Add more debug info to TFTP helper. # # From Vineet Mehta # # net/ipv4/netfilter/ip_conntrack_tftp.c # 2004/04/09 16:34:39-07:00 laforge@netfilter.org +7 -0 # [NETFILTER]: Add more debug info to TFTP helper. # # From Vineet Mehta # # include/linux/netfilter_ipv4/ip_conntrack_tftp.h # 2004/04/09 16:34:39-07:00 laforge@netfilter.org +3 -0 # [NETFILTER]: Add more debug info to TFTP helper. # # From Vineet Mehta # # ChangeSet # 2004/04/09 16:32:02-07:00 rddunlap@osdl.org # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/ipv4/netfilter/ipt_ULOG.c # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +3 -3 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/ipv4/netfilter/ip_nat_tftp.c # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +2 -2 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/ipv4/netfilter/ip_conntrack_tftp.c # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +2 -2 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/ipv4/netfilter/ip_conntrack_irc.c # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +2 -2 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/8021q/vlanproc.c # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +1 -1 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # net/8021q/vlan.h # 2004/04/09 16:31:49-07:00 rddunlap@osdl.org +2 -2 # [NET]: Kill __FUNCTION__ string literal concatenation. # # From Tony Breeds # # ChangeSet # 2004/04/09 16:30:19-07:00 weeve@gentoo.org # [SOUND]: Add amd7930 to sndmagic.h # # include/sound/sndmagic.h # 2004/04/09 16:30:06-07:00 weeve@gentoo.org +1 -0 # [SOUND]: Add amd7930 to sndmagic.h # # ChangeSet # 2004/04/09 16:29:14-07:00 weeve@gentoo.org # [SOUND]: Proper deps for SND_BIT32_EMUL. # # sound/core/Kconfig # 2004/04/09 16:29:00-07:00 weeve@gentoo.org +1 -1 # [SOUND]: Proper deps for SND_BIT32_EMUL. # # ChangeSet # 2004/04/09 16:27:28-07:00 mashirle@us.ibm.com # [IPV6]: Add missing MIB counter increments. # # net/ipv6/reassembly.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +5 -0 # [IPV6]: Add missing MIB counter increments. # # net/ipv6/raw.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +1 -0 # [IPV6]: Add missing MIB counter increments. # # net/ipv6/ndisc.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +4 -0 # [IPV6]: Add missing MIB counter increments. # # net/ipv6/ip6_output.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +22 -5 # [IPV6]: Add missing MIB counter increments. # # net/ipv6/ip6_input.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +7 -2 # [IPV6]: Add missing MIB counter increments. # # net/ipv6/exthdrs.c # 2004/04/09 16:27:15-07:00 mashirle@us.ibm.com +15 -1 # [IPV6]: Add missing MIB counter increments. # # ChangeSet # 2004/04/09 16:21:48-07:00 kkeil@suse.de # [ISDN]: Fix kernel PPP/IPPP active/passiv filter code. # # drivers/net/ppp_generic.c # 2004/04/09 16:21:06-07:00 kkeil@suse.de +10 -2 # [ISDN]: Fix kernel PPP/IPPP active/passiv filter code. # # drivers/isdn/i4l/isdn_ppp.c # 2004/04/09 16:21:06-07:00 kkeil@suse.de +21 -6 # [ISDN]: Fix kernel PPP/IPPP active/passiv filter code. # # ChangeSet # 2004/04/09 16:03:30-07:00 davem@nuts.davemloft.net # [ISDN]: Add missing IPPP_FILTER entry to Kconfig. # # drivers/isdn/i4l/Kconfig # 2004/04/09 16:03:17-07:00 davem@nuts.davemloft.net +11 -0 # [ISDN]: Add missing IPPP_FILTER entry to Kconfig. # # ChangeSet # 2004/04/09 15:47:47-07:00 agruen@suse.de # [IPSEC]: Support draft-ietf-ipsec-udp-encaps-00/01, some ipec impls need it. # # net/ipv4/udp.c # 2004/04/09 15:47:34-07:00 agruen@suse.de +15 -0 # [IPSEC]: Support draft-ietf-ipsec-udp-encaps-00/01, some ipec impls need it. # # net/ipv4/esp4.c # 2004/04/09 15:47:34-07:00 agruen@suse.de +22 -0 # [IPSEC]: Support draft-ietf-ipsec-udp-encaps-00/01, some ipec impls need it. # # include/linux/udp.h # 2004/04/09 15:47:34-07:00 agruen@suse.de +1 -0 # [IPSEC]: Support draft-ietf-ipsec-udp-encaps-00/01, some ipec impls need it. # # ChangeSet # 2004/04/09 15:29:23-07:00 davem@nuts.davemloft.net # [IPV6]: In ndisc_netdev_event, handle NETDEV_DOWN. # # Based upon patches and commentary from Thomas Spatzier, # Stephen Hemminger, and Andi Kleen. # # net/ipv6/ndisc.c # 2004/04/09 15:29:00-07:00 davem@nuts.davemloft.net +4 -0 # [IPV6]: In ndisc_netdev_event, handle NETDEV_DOWN. # # Based upon patches and commentary from Thomas Spatzier, # Stephen Hemminger, and Andi Kleen. # # ChangeSet # 2004/04/09 11:51:13-07:00 hannal@us.ibm.com # [PATCH] Fix class support to istallion.c # # Realized I put a / in the filename of this device too. # # Here is the fix: # # drivers/char/istallion.c # 2004/04/08 16:26:44-07:00 hannal@us.ibm.com +1 -1 # Fix class support to istallion.c # # ChangeSet # 2004/04/09 11:50:55-07:00 hannal@us.ibm.com # [PATCH] Fix for patch to add class support to stallion.c # # Oops. Realized I had a / in the file name in this patch too. # # Please apply to correct it: # # drivers/char/stallion.c # 2004/04/08 16:16:11-07:00 hannal@us.ibm.com +1 -1 # Fix for patch to add class support to stallion.c # # ChangeSet # 2004/04/09 11:50:34-07:00 hannal@us.ibm.com # [PATCH] fix sysfs class support to fs/coda/psdev.c # # --On Friday, April 09, 2004 12:02:19 AM +0200 Marcel Holtmann wrote: # >> +static struct class_simple coda_psdev_class; # > # > I think coda_psdev_class must be a pointer. # > # > Regards # > # > Marcel # # # Doh! I tested on one system and fixed this there. Then accidentally mailed out the # original. Sorry about that. Here is a patch to fix it: # # fs/coda/psdev.c # 2004/04/08 15:37:15-07:00 hannal@us.ibm.com +1 -1 # fix sysfs class support to fs/coda/psdev.c # # ChangeSet # 2004/04/09 11:32:55-07:00 marcel@holtmann.org # [PATCH] Add sysfs class support for CAPI # # here is a patch that adds class support to the ISDN CAPI module. Without # it udev won't create the /dev/capi20 device node. # # drivers/isdn/capi/capi.c # 2004/04/08 17:00:37-07:00 marcel@holtmann.org +14 -0 # Add sysfs class support for CAPI # # ChangeSet # 2004/04/09 19:17:36+02:00 marcel@holtmann.org # [Bluetooth] Fix race in RX complete routine of the USB drivers # # The test of the HCI_RUNNING flags bit in the RX complete routine should # be made while holding the completion lock. Otherwise there can be a race # on SMP systems in which RX complete finds the bit is set and on another # processor the close routine clears the bit, grabs and releases the lock # and then unlinks all the active URB's. Then the first processor acquires # the lock and resubmits the URB. # # Patch from Alan Stern # # drivers/bluetooth/hci_usb.c # 2004/04/09 19:12:26+02:00 marcel@holtmann.org +5 -5 # Fix race in RX complete routine of the USB drivers # # drivers/bluetooth/bfusb.c # 2004/04/09 19:12:02+02:00 marcel@holtmann.org +4 -3 # Fix race in RX complete routine of the USB drivers # # ChangeSet # 2004/04/09 19:00:06+02:00 marcel@holtmann.org # [Bluetooth] Allow normal users to release the previous created TTY # # In the case the RFCOMM device node can't be found, the user must be able to # release the previous created TTY. # # net/bluetooth/rfcomm/tty.c # 2004/04/09 18:54:24+02:00 marcel@holtmann.org +6 -4 # Allow normal users to release the previous created TTY # # ChangeSet # 2004/04/09 10:06:41-04:00 bcollins@debian.org # [SBP2]: Sync revision # # drivers/ieee1394/sbp2.c # 2004/04/09 10:04:12-04:00 bcollins@debian.org +1 -1 # [SBP2]: Sync revision # # ChangeSet # 2004/04/09 10:03:57-04:00 bcollins@debian.org # [Kconfig]: eth1394 requires INET # # drivers/ieee1394/Kconfig # 2004/04/09 10:02:35-04:00 bcollins@debian.org +1 -1 # [Kconfig]: eth1394 requires INET # # ChangeSet # 2004/04/09 09:09:02-04:00 bcollins@debian.org # [SBP2]: Fix compile for older gcc's # # drivers/ieee1394/sbp2.c # 2004/04/09 09:06:53-04:00 bcollins@debian.org +4 -2 # [SBP2]: Fix compile for older gcc's # # ChangeSet # 2004/04/09 01:27:17+02:00 marcel@holtmann.org # [Bluetooth] Add support for Anycom CF-300 # # The Anycom CF-300 compact flash card contains a new Bluetooth chip and # thus it needs some special handling for the faster UART baud rate. This # patch detects this new card and does the different initialization. # # drivers/bluetooth/bluecard_cs.c # 2004/04/09 01:22:55+02:00 marcel@holtmann.org +40 -5 # Add support for Anycom CF-300 # # ChangeSet # 2004/04/09 01:21:54+02:00 marcel@holtmann.org # [Bluetooth] Improve NULL pointer handling # # This small patch adds more checks for NULL pointers. # # drivers/bluetooth/btuart_cs.c # 2004/04/09 01:21:32+02:00 marcel@holtmann.org +4 -0 # Improve NULL pointer handling # # drivers/bluetooth/dtl1_cs.c # 2004/04/09 01:21:30+02:00 marcel@holtmann.org +4 -0 # Improve NULL pointer handling # # ChangeSet # 2004/04/09 01:20:41+02:00 marcel@holtmann.org # [Bluetooth] Make use of request_firmware() for the 3Com driver # # The 3Com Bluetooth PCMCIA cards need a firmware download every time they # are inserted. With request_firmware() the file BT3CPCC.bin is now loaded # directly from the userspace and the external firmware loader program is # no longer needed. # # drivers/bluetooth/bt3c_cs.c # 2004/04/09 01:19:53+02:00 marcel@holtmann.org +109 -21 # Make use of request_firmware() for the 3Com driver # # drivers/bluetooth/Kconfig # 2004/04/09 01:19:50+02:00 marcel@holtmann.org +1 -3 # Make use of request_firmware() for the 3Com driver # # ChangeSet # 2004/04/09 01:01:09+02:00 marcel@holtmann.org # [Bluetooth] Fix URB unlink race in the USB drivers # # The code in hci_usb_unlink_urbs() calls usb_unlink_urb() to perform a # synchronous unlink of each pending URB. It then moves each URB to the # completed list, and then frees everything on the completed list. By doing # this, the code implicitly assumes that when usb_unlink_urb() returns the # URB will have completed and be ready to be deallocated. That's not always # true. The same applies to the BlueFRITZ! USB driver. # # Patch from Alan Stern # # drivers/bluetooth/hci_usb.c # 2004/04/09 00:58:38+02:00 marcel@holtmann.org +9 -0 # Fix URB unlink race in the USB drivers # # drivers/bluetooth/bfusb.c # 2004/04/09 00:58:32+02:00 marcel@holtmann.org +10 -1 # Fix URB unlink race in the USB drivers # # ChangeSet # 2004/04/08 14:53:05-07:00 hannal@us.ibm.com # [PATCH] Add sysfs class support to fs/coda/psdev.c # # Here is a patch to add class support to psdev.c. # # I have verified it compiles and works. # # fs/coda/psdev.c # 2004/04/08 14:05:51-07:00 hannal@us.ibm.com +31 -5 # Add sysfs class support to fs/coda/psdev.c # # ChangeSet # 2004/04/08 14:45:41-07:00 hannal@us.ibm.com # [PATCH] add class support to dsp56k.c # # Here is a patch that adds sysfs class support to /drivers/char/dsp56k.c # # drivers/char/dsp56k.c # 2004/04/08 09:53:57-07:00 hannal@us.ibm.com +25 -2 # add class support to dsp56k.c # # ChangeSet # 2004/04/08 13:34:53-07:00 shemminger@osdl.org # [NET]: Use const args in eth_copy_and_sum and is_valid_ether_addr. # # include/linux/etherdevice.h # 2004/04/08 13:34:38-07:00 shemminger@osdl.org +4 -2 # [NET]: Use const args in eth_copy_and_sum and is_valid_ether_addr. # # ChangeSet # 2004/04/07 16:10:06-07:00 dlsy@snoqualmie.dp.intel.com # [PATCH] PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug # # This patch contains fixes for interpretation of 0/1 for MRL # to match pcihpview, bus speed definition in shpchp_hpc.c etc. # # drivers/pci/hotplug/shpchp_hpc.c # 2004/03/30 17:17:16-08:00 dlsy@snoqualmie.dp.intel.com +8 -7 # PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug # # drivers/pci/hotplug/shpchp_ctrl.c # 2004/04/01 08:52:26-08:00 dlsy@snoqualmie.dp.intel.com +5 -5 # PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug # # drivers/pci/hotplug/pciehp_ctrl.c # 2004/03/30 15:25:32-08:00 dlsy@snoqualmie.dp.intel.com +3 -3 # PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug # # drivers/pci/hotplug/pci_hotplug.h # 2004/03/30 17:14:27-08:00 dlsy@snoqualmie.dp.intel.com +1 -1 # PCI Hotplug: Fix interpretation of 0/1 for MRL in SHPC & PCI-E hot-plug # # ChangeSet # 2004/04/06 10:39:30-07:00 davem@nuts.davemloft.net # Merge http://linux-lksctp.bkbits.net/lksctp-2.5.work # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/key/af_key.c # 2004/04/06 10:39:22-07:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/04/06 11:38:41-04:00 khawar.chaudhry@amd.com # Update amd8111 net driver. # # version 3.04 for 2.4 kernel: # + 1. Added set_mac_address routine for bonding driver support. # + 2. Tested the driver for bonding support # + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth # + indicated to the h/w. # + 4. Modified amd8111e_rx() routine to receive all the received packets # + in the first interrupt. # + 5. Bug fix: Corrected rx_errors reported in get_stats() function. # # version 3.05 for 2.6 kernel: # + 1. Added NAPI support # # # drivers/net/amd8111e.h # 2004/04/06 11:38:36-04:00 khawar.chaudhry@amd.com +2 -1 # Update amd8111 net driver. # # version 3.04 for 2.4 kernel: # + 1. Added set_mac_address routine for bonding driver support. # + 2. Tested the driver for bonding support # + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth # + indicated to the h/w. # + 4. Modified amd8111e_rx() routine to receive all the received packets # + in the first interrupt. # + 5. Bug fix: Corrected rx_errors reported in get_stats() function. # # version 3.05 for 2.6 kernel: # + 1. Added NAPI support # # # drivers/net/amd8111e.c # 2004/04/06 11:38:36-04:00 khawar.chaudhry@amd.com +212 -15 # Update amd8111 net driver. # # version 3.04 for 2.4 kernel: # + 1. Added set_mac_address routine for bonding driver support. # + 2. Tested the driver for bonding support # + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth # + indicated to the h/w. # + 4. Modified amd8111e_rx() routine to receive all the received packets # + in the first interrupt. # + 5. Bug fix: Corrected rx_errors reported in get_stats() function. # # version 3.05 for 2.6 kernel: # + 1. Added NAPI support # # # drivers/net/Kconfig # 2004/04/06 11:38:36-04:00 khawar.chaudhry@amd.com +3 -0 # Update amd8111 net driver. # # version 3.04 for 2.4 kernel: # + 1. Added set_mac_address routine for bonding driver support. # + 2. Tested the driver for bonding support # + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth # + indicated to the h/w. # + 4. Modified amd8111e_rx() routine to receive all the received packets # + in the first interrupt. # + 5. Bug fix: Corrected rx_errors reported in get_stats() function. # # version 3.05 for 2.6 kernel: # + 1. Added NAPI support # # # ChangeSet # 2004/04/06 17:25:16+02:00 marcel@holtmann.org # [Bluetooth] Allocate the BCM203x URB buffer seperately # # The buffer shares cachelines with other fields of the structure. On # architectures which require synchronisation before or after doing DMA # to or from a buffer, any access to such fields sharing cachelines can # corrupt the content of the buffer. The allocation primitives guarantee # that cachelines are not shared. # # Noticed by Oliver Neukum # # drivers/bluetooth/bcm203x.c # 2004/04/06 17:24:06+02:00 marcel@holtmann.org +19 -20 # Allocate the BCM203x URB buffer seperately # # ChangeSet # 2004/04/06 07:32:30-07:00 sri@us.ibm.com # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # net/sctp/socket.c # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +8 -2 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # net/sctp/sm_make_chunk.c # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +15 -3 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # net/sctp/protocol.c # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +6 -0 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # net/sctp/associola.c # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +11 -26 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # include/net/sctp/structs.h # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +3 -6 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # include/net/sctp/sctp.h # 2004/04/06 07:32:14-07:00 sri@us.ibm.com +6 -20 # [SCTP] Use id to ptr translation service in lib/idr.c to assign and # validate ids of associations. # # This patch avoids the use of virt_addr_valid() to validate the address # of associations passed by the user. Currently the address of an # association is used as its id. virt_addr_valid doesn't work as # expected when PAGEALLOC debugging is enabled. # # ChangeSet # 2004/04/06 07:24:04-07:00 sri@us.ibm.com # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # net/sctp/ulpqueue.c # 2004/04/06 07:23:47-07:00 sri@us.ibm.com +22 -22 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # net/sctp/ulpevent.c # 2004/04/06 07:23:47-07:00 sri@us.ibm.com +84 -100 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # net/sctp/socket.c # 2004/04/06 07:23:47-07:00 sri@us.ibm.com +3 -4 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # net/sctp/protocol.c # 2004/04/06 07:23:46-07:00 sri@us.ibm.com +1 -1 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # net/sctp/ipv6.c # 2004/04/06 07:23:46-07:00 sri@us.ibm.com +2 -2 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # include/net/sctp/ulpevent.h # 2004/04/06 07:23:46-07:00 sri@us.ibm.com +8 -2 # [SCTP] Update sctp_ulpevent structure to include assoc pointer and # only the receive specific fields of sctp_sndrcvinfo. # # ChangeSet # 2004/04/06 09:23:17-04:00 akpm@osdl.org # [PATCH] com20020-isa.c warning fix # # From: "Luiz Fernando N. Capitulino" # # drivers/net/arcnet/com20020-isa.c:188: warning: unused variable `dev' # drivers/net/arcnet/com20020-isa.c:189: warning: unused variable `lp' # # drivers/net/arcnet/com20020-isa.c # 2004/04/06 05:23:12-04:00 akpm@osdl.org +0 -2 # [PATCH] com20020-isa.c warning fix # # From: "Luiz Fernando N. Capitulino" # # drivers/net/arcnet/com20020-isa.c:188: warning: unused variable `dev' # drivers/net/arcnet/com20020-isa.c:189: warning: unused variable `lp' # # ChangeSet # 2004/04/06 09:23:04-04:00 scott.feldman@intel.com # [PATCH] Update MAINTAINERS with new e100/e1000/ixgb maintainers # # Jeff, Adding John/Ganesh/Ayyappan for e100/e100/ixgb in 2.6. Keeping # myself on for e100 for a couple more 2.6.x releases. # # -scott # # MAINTAINERS # 2004/04/06 05:22:58-04:00 scott.feldman@intel.com +15 -5 # [PATCH] Update MAINTAINERS with new e100/e1000/ixgb maintainers # # Jeff, Adding John/Ganesh/Ayyappan for e100/e100/ixgb in 2.6. Keeping # myself on for e100 for a couple more 2.6.x releases. # # -scott # # ChangeSet # 2004/04/06 09:22:46-04:00 jgarzik@redhat.com # [netdrvr natsemi] correct DP83816 IntrHoldoff register offset # # Spotted by Manfred Spraul. # # drivers/net/natsemi.c # 2004/04/06 05:22:41-04:00 jgarzik@redhat.com +1 -1 # [netdrvr natsemi] correct DP83816 IntrHoldoff register offset # # Spotted by Manfred Spraul. # # ChangeSet # 2004/04/06 09:21:40-04:00 jgarzik@redhat.com # [NET] define HAVE_NETDEV_PRIV back-compat hook # # include/linux/netdevice.h # 2004/04/06 05:21:33-04:00 jgarzik@redhat.com +3 -2 # [NET] define HAVE_NETDEV_PRIV back-compat hook # # ChangeSet # 2004/04/06 09:18:52-04:00 jgarzik@redhat.com # [net/fc iph5526] s/rx_dropped/tx_dropped/ in TX routines # # Spotted by Denis Valesko(sp?). # # Maybe one day we'll either kill this driver, or someone will fix it # up for the current SCSI API. # # drivers/net/fc/iph5526.c # 2004/04/06 05:17:19-04:00 jgarzik@redhat.com +2 -2 # [net/fc iph5526] s/rx_dropped/tx_dropped/ in TX routines # # Spotted by Denis Valesko(sp?). # # Maybe one day we'll either kill this driver, or someone will fix it # up for the current SCSI API. # # ChangeSet # 2004/04/06 07:35:19-04:00 bcollins@debian.org # [IEEE-1394] Sync IEEE-1394 to r1203 # # drivers/ieee1394/video1394.h # 2004/04/06 07:34:16-04:00 bcollins@debian.org +2 -2 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/csr1212.h # 2004/04/06 07:34:16-04:00 bcollins@debian.org +4 -3 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/csr1212.c # 2004/04/06 07:34:16-04:00 bcollins@debian.org +13 -16 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/video1394.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +81 -80 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/sbp2.h # 2004/04/06 07:34:15-04:00 bcollins@debian.org +11 -11 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/sbp2.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +95 -88 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/raw1394.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +107 -108 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/raw1394-private.h # 2004/04/06 07:34:15-04:00 bcollins@debian.org +1 -1 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/pcilynx.h # 2004/04/06 07:34:15-04:00 bcollins@debian.org +10 -10 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/pcilynx.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +40 -43 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ohci1394.h # 2004/04/06 07:34:15-04:00 bcollins@debian.org +10 -10 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ohci1394.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +178 -194 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/nodemgr.h # 2004/04/06 07:34:15-04:00 bcollins@debian.org +3 -3 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/nodemgr.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +17 -18 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/iso.c # 2004/04/06 07:34:15-04:00 bcollins@debian.org +2 -2 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ieee1394_transactions.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +22 -22 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ieee1394_core.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +12 -6 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ieee1394_core.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +133 -141 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/ieee1394.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +2 -2 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/hosts.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +5 -3 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/hosts.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +1 -3 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/highlevel.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +7 -7 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/highlevel.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +1 -1 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/eth1394.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +26 -30 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/dv1394.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +17 -17 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/dv1394.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +207 -210 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/dv1394-private.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +42 -43 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/dma.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +2 -2 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/dma.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +12 -1 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/csr.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +16 -16 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/cmp.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +6 -6 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/amdtp.h # 2004/04/06 07:34:14-04:00 bcollins@debian.org +1 -1 # Sync IEEE-1394 to r1203 # # drivers/ieee1394/amdtp.c # 2004/04/06 07:34:14-04:00 bcollins@debian.org +20 -19 # Sync IEEE-1394 to r1203 # # ChangeSet # 2004/04/06 00:28:31-07:00 sri@us.ibm.com # [SCTP] Fix typo in entry name of the remove_proc_entry() call. # # net/sctp/objcnt.c # 2004/04/06 00:28:09-07:00 sri@us.ibm.com +2 -2 # [SCTP] Fix typo in entry name of the remove_proc_entry() call. # # ChangeSet # 2004/04/05 15:23:03-07:00 rddunlap@osdl.org # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # net/irda/Kconfig # 2004/04/05 15:22:50-07:00 rddunlap@osdl.org +2 -6 # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # net/bluetooth/Kconfig # 2004/04/05 15:22:50-07:00 rddunlap@osdl.org +1 -5 # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # net/ax25/Kconfig # 2004/04/05 15:22:50-07:00 rddunlap@osdl.org +2 -5 # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # net/Kconfig # 2004/04/05 15:22:50-07:00 rddunlap@osdl.org +62 -61 # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # drivers/net/Kconfig # 2004/04/05 15:22:50-07:00 rddunlap@osdl.org +26 -27 # [NET]: Update networking config menu (v3) # # Networking support/options and Networking drivers have been, uhm, # messy to navigate for some time now. BenH mentioned this # and I was already looking into options to clean it up. # # This is a cleanup of Networking support/options and Networking Drivers. # It presents a more consistent interface and lists similar driver # groups and protocol groups closer together. # It also moves the IBMVETH driver so that it no longer breaks the # dependency tree, allowing other drivers (nearby in Kconfig file) # to be presented in a more linear manner. # # ChangeSet # 2004/04/05 14:51:37-07:00 manfred@colorfullife.com # [NETLINK]: Split up netlink_unicast. # # net/netlink/af_netlink.c # 2004/04/05 14:51:24-07:00 manfred@colorfullife.com +94 -26 # [NETLINK]: Split up netlink_unicast. # # include/linux/netlink.h # 2004/04/05 14:51:24-07:00 manfred@colorfullife.com +7 -0 # [NETLINK]: Split up netlink_unicast. # # ChangeSet # 2004/04/05 14:42:00-07:00 mashirle@us.ibm.com # [IPV6]: Provide ipv6 multicast/anycast addresses through netlink. # # net/ipv6/addrconf.c # 2004/04/05 14:41:40-07:00 mashirle@us.ibm.com +157 -22 # [IPV6]: Provide ipv6 multicast/anycast addresses through netlink. # # include/linux/rtnetlink.h # 2004/04/05 14:41:40-07:00 mashirle@us.ibm.com +7 -2 # [IPV6]: Provide ipv6 multicast/anycast addresses through netlink. # # ChangeSet # 2004/04/05 15:50:57+02:00 marcel@holtmann.org # [Bluetooth] Add UART protocol id's for 3-Wire and H4DS # # This patch adds the id's for the 3-Wire and H4DS UART transport protocols. # # drivers/bluetooth/hci_uart.h # 2004/04/05 15:45:30+02:00 marcel@holtmann.org +3 -2 # Add UART protocol id's for 3-Wire and H4DS # # ChangeSet # 2004/04/05 11:36:39+02:00 marcel@holtmann.org # [Bluetooth] Allocate hdev before device configuration # # The hdev structure must be allocated before the device is configured and # before any interrupt is started. # # drivers/bluetooth/btuart_cs.c # 2004/04/05 11:34:41+02:00 marcel@holtmann.org +23 -23 # Allocate hdev before device configuration # # drivers/bluetooth/bt3c_cs.c # 2004/04/05 11:34:39+02:00 marcel@holtmann.org +19 -19 # Allocate hdev before device configuration # # drivers/bluetooth/bluecard_cs.c # 2004/04/05 11:34:37+02:00 marcel@holtmann.org +24 -24 # Allocate hdev before device configuration # # drivers/bluetooth/dtl1_cs.c # 2004/04/05 11:33:15+02:00 marcel@holtmann.org +23 -23 # Allocate hdev before device configuration # # ChangeSet # 2004/04/05 11:00:19+02:00 marcel@holtmann.org # [Bluetooth] Fix broken HCI security filter # # The HCI security filter is broken on 64-bit architectures and this patch # restores the version from 2.4, which is working perfect on 32-bit and # 64-bit machines. # # net/bluetooth/hci_sock.c # 2004/04/05 10:58:22+02:00 marcel@holtmann.org +9 -4 # Fix broken HCI security filter # # include/net/bluetooth/hci_core.h # 2004/04/05 10:58:01+02:00 marcel@holtmann.org +3 -3 # Fix broken HCI security filter # # ChangeSet # 2004/04/05 10:51:15+02:00 marcel@holtmann.org # [Bluetooth] Remove architecture specific compat ioctl's # # The compat ioctl definitions are now maintained in a single place, so # it is no longer needed to keep the architecture specific defines. This # patch removes the leftover Bluetooth parts from x86_64 and sparc64. # # arch/x86_64/ia32/ia32_ioctl.c # 2004/04/05 10:41:53+02:00 marcel@holtmann.org +0 -11 # Remove architecture specific compat ioctl's # # arch/sparc64/kernel/ioctl32.c # 2004/04/05 10:41:15+02:00 marcel@holtmann.org +0 -11 # Remove architecture specific compat ioctl's # # ChangeSet # 2004/04/05 00:02:12-04:00 jgarzik@redhat.com # Merge redhat.com:/spare/repo/linux-2.6 # into redhat.com:/spare/repo/misc-2.6 # # MAINTAINERS # 2004/04/05 00:02:07-04:00 jgarzik@redhat.com +0 -0 # Auto merged # # ChangeSet # 2004/04/03 20:32:58-08:00 davem@nuts.davemloft.net # [SPARC64]: hugetlbpage.c needs module.h # # arch/sparc64/mm/hugetlbpage.c # 2004/04/03 20:32:41-08:00 davem@nuts.davemloft.net +1 -0 # [SPARC64]: hugetlbpage.c needs module.h # # ChangeSet # 2004/04/03 20:06:01-08:00 davem@nuts.davemloft.net # Merge nuts.davemloft.net:/disk1/BK/sparcwork-2.6 # into nuts.davemloft.net:/disk1/BK/sparc-2.6 # # kernel/sysctl.c # 2004/04/03 20:05:53-08:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # include/linux/sysctl.h # 2004/04/03 20:05:53-08:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/04/03 14:43:21-08:00 ebrower@usa.net # [SPARC]: Add sysctl to control serial console power-off restrictions. # # kernel/sysctl.c # 2004/04/03 14:43:03-08:00 ebrower@usa.net +9 -0 # [SPARC]: Add sysctl to control serial console power-off restrictions. # # include/linux/sysctl.h # 2004/04/03 14:43:03-08:00 ebrower@usa.net +1 -0 # [SPARC]: Add sysctl to control serial console power-off restrictions. # # arch/sparc64/kernel/power.c # 2004/04/03 14:43:03-08:00 ebrower@usa.net +7 -1 # [SPARC]: Add sysctl to control serial console power-off restrictions. # # arch/sparc/kernel/process.c # 2004/04/03 14:43:03-08:00 ebrower@usa.net +7 -1 # [SPARC]: Add sysctl to control serial console power-off restrictions. # # ChangeSet # 2004/04/03 14:30:00-08:00 mashirle@us.ibm.com # [IPV6]: Add MIBs counters in MLD. # # net/ipv6/mcast.c # 2004/04/03 14:29:40-08:00 mashirle@us.ibm.com +14 -3 # [IPV6]: Add MIBs counters in MLD. # # ChangeSet # 2004/04/03 13:20:34-08:00 davem@nuts.davemloft.net # [TG3]: Update driver version and release date. # # drivers/net/tg3.c # 2004/04/03 13:20:20-08:00 davem@nuts.davemloft.net +2 -2 # [TG3]: Update driver version and release date. # # ChangeSet # 2004/04/03 13:19:11-08:00 davem@nuts.davemloft.net # [TG3]: Reset fixes. # # - Put more code into common area in tg3_chip_reset() # - Set GRC_MODE, even sanes host-stackup bit, after enabling # memory arbiter. # - After every core-clock reset, reprobe ASF enabling state. # # drivers/net/tg3.c # 2004/04/03 13:18:55-08:00 davem@nuts.davemloft.net +52 -61 # [TG3]: Reset fixes. # # - Put more code into common area in tg3_chip_reset() # - Set GRC_MODE, even sanes host-stackup bit, after enabling # memory arbiter. # - After every core-clock reset, reprobe ASF enabling state. # # ChangeSet # 2004/04/03 12:25:29-08:00 davem@nuts.davemloft.net # [TG3]: Kill uninitialized var warning. # # drivers/net/tg3.c # 2004/04/03 12:25:16-08:00 davem@nuts.davemloft.net +1 -1 # [TG3]: Kill uninitialized var warning. # # ChangeSet # 2004/04/03 12:20:33-08:00 davem@nuts.davemloft.net # [TG3]: Two PHY fixes. # # - Do not probe PHY ID register if ASF firmware is running. # - Fix two errors in PCI subsys to PHY ID table. # # drivers/net/tg3.c # 2004/04/03 12:20:20-08:00 davem@nuts.davemloft.net +21 -13 # [TG3]: Two PHY fixes. # # - Do not probe PHY ID register if ASF firmware is running. # - Fix two errors in PCI subsys to PHY ID table. # # ChangeSet # 2004/04/03 00:26:27-08:00 davem@nuts.davemloft.net # [TG3]: Print list of important probed capabilities at driver load. # # drivers/net/tg3.c # 2004/04/03 00:26:08-08:00 davem@nuts.davemloft.net +13 -0 # [TG3]: Print list of important probed capabilities at driver load. # # ChangeSet # 2004/04/01 14:21:37-08:00 davem@nuts.davemloft.net # [TG3]: Bump driver version and reldate. # # drivers/net/tg3.c # 2004/04/01 14:21:20-08:00 davem@nuts.davemloft.net +2 -2 # [TG3]: Bump driver version and reldate. # # ChangeSet # 2004/04/01 14:19:26-08:00 davem@nuts.davemloft.net # [TG3]: More PHY programming fixes. # # - Break out advertisement register verification into # a function, tg3_copper_is_advertising_all. # - At device probe time, reset PHY if not Serdes # and ASF is not enabled. # - Add some missing necessary PHY init to PHY probe # code as well. # # drivers/net/tg3.c # 2004/04/01 14:18:46-08:00 davem@nuts.davemloft.net +72 -34 # [TG3]: More PHY programming fixes. # # - Break out advertisement register verification into # a function, tg3_copper_is_advertising_all. # - At device probe time, reset PHY if not Serdes # and ASF is not enabled. # - Add some missing necessary PHY init to PHY probe # code as well. # # ChangeSet # 2004/04/01 14:12:40-08:00 shemminger@osdl.org # [BRIDGE]: Correctly handle up to 256 ports per bridge. # # Bridge code is limited to 256 ports per bridge because the Spanning # Tree Protocol has limit of one octet for port number. This code # fixes: # * bogus unlock in error path when port list is full. # * passes different error status for out of memory, vs # port list full. # * O(n) vs O(n^2) lookup for free port number # * since port and priority are both limited to one byte # don't store them as int's # * makes limit explicit in code # # net/bridge/br_private.h # 2004/04/01 14:12:27-08:00 shemminger@osdl.org +2 -2 # [BRIDGE]: Correctly handle up to 256 ports per bridge. # # Bridge code is limited to 256 ports per bridge because the Spanning # Tree Protocol has limit of one octet for port number. This code # fixes: # * bogus unlock in error path when port list is full. # * passes different error status for out of memory, vs # port list full. # * O(n) vs O(n^2) lookup for free port number # * since port and priority are both limited to one byte # don't store them as int's # * makes limit explicit in code # # net/bridge/br_if.c # 2004/04/01 14:12:27-08:00 shemminger@osdl.org +32 -17 # [BRIDGE]: Correctly handle up to 256 ports per bridge. # # Bridge code is limited to 256 ports per bridge because the Spanning # Tree Protocol has limit of one octet for port number. This code # fixes: # * bogus unlock in error path when port list is full. # * passes different error status for out of memory, vs # port list full. # * O(n) vs O(n^2) lookup for free port number # * since port and priority are both limited to one byte # don't store them as int's # * makes limit explicit in code # # ChangeSet # 2004/04/01 13:48:59-08:00 shemminger@osdl.org # [BRIDGE]: Lift ioctl limits on number of bridges/ports. # # Get rid of some arbitrary API restrictions that limit the kernel # to 64 bridges and 256 ports. # # Retain compatibility in GET_PORT_LIST, the existing bridge API # passes 0 for the third argument, and expects 256 entries. # # Note: there still is limit of 256 ports due to STP, but this # shouldn't show up in the API, it needs to be handled by the # 'add port to bridge ioctl'. # # net/bridge/br_private.h # 2004/04/01 13:48:46-08:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Lift ioctl limits on number of bridges/ports. # # Get rid of some arbitrary API restrictions that limit the kernel # to 64 bridges and 256 ports. # # Retain compatibility in GET_PORT_LIST, the existing bridge API # passes 0 for the third argument, and expects 256 entries. # # Note: there still is limit of 256 ports due to STP, but this # shouldn't show up in the API, it needs to be handled by the # 'add port to bridge ioctl'. # # net/bridge/br_ioctl.c # 2004/04/01 13:48:46-08:00 shemminger@osdl.org +6 -8 # [BRIDGE]: Lift ioctl limits on number of bridges/ports. # # Get rid of some arbitrary API restrictions that limit the kernel # to 64 bridges and 256 ports. # # Retain compatibility in GET_PORT_LIST, the existing bridge API # passes 0 for the third argument, and expects 256 entries. # # Note: there still is limit of 256 ports due to STP, but this # shouldn't show up in the API, it needs to be handled by the # 'add port to bridge ioctl'. # # net/bridge/br_if.c # 2004/04/01 13:48:46-08:00 shemminger@osdl.org +3 -2 # [BRIDGE]: Lift ioctl limits on number of bridges/ports. # # Get rid of some arbitrary API restrictions that limit the kernel # to 64 bridges and 256 ports. # # Retain compatibility in GET_PORT_LIST, the existing bridge API # passes 0 for the third argument, and expects 256 entries. # # Note: there still is limit of 256 ports due to STP, but this # shouldn't show up in the API, it needs to be handled by the # 'add port to bridge ioctl'. # # ChangeSet # 2004/04/01 13:47:12-08:00 davem@nuts.davemloft.net # [TG3]: All 5705 chips need PHY reset on link-down. # # drivers/net/tg3.c # 2004/04/01 13:46:55-08:00 davem@nuts.davemloft.net +1 -1 # [TG3]: All 5705 chips need PHY reset on link-down. # # ChangeSet # 2004/04/01 13:37:15-08:00 shemminger@osdl.org # [BRIDGE]: Allow non-root to inspect the status of a bridge. # # net/bridge/br_private.h # 2004/04/01 13:37:02-08:00 shemminger@osdl.org +5 -5 # [BRIDGE]: Allow non-root to inspect the status of a bridge. # # net/bridge/br_ioctl.c # 2004/04/01 13:37:02-08:00 shemminger@osdl.org +32 -25 # [BRIDGE]: Allow non-root to inspect the status of a bridge. # # net/bridge/br_device.c # 2004/04/01 13:37:02-08:00 shemminger@osdl.org +1 -1 # [BRIDGE]: Allow non-root to inspect the status of a bridge. # # ChangeSet # 2004/04/01 11:49:08-08:00 dlstevens@us.ibm.com # [IPV4]: Fix IGMP version number and timer printing for procfs. # # net/ipv4/igmp.c # 2004/04/01 11:48:55-08:00 dlstevens@us.ibm.com +6 -2 # [IPV4]: Fix IGMP version number and timer printing for procfs. # # ChangeSet # 2004/04/01 11:31:09-08:00 davem@nuts.davemloft.net # [TG3]: Verify link advertisement correctly on 10/100 only chips. # # drivers/net/tg3.c # 2004/04/01 11:30:51-08:00 davem@nuts.davemloft.net +2 -1 # [TG3]: Verify link advertisement correctly on 10/100 only chips. # # ChangeSet # 2004/04/01 10:38:01-08:00 mludvig@suse.cz # [AF_KEY]: pfkey_send_new_mapping marks dest address incorrectly. # # net/key/af_key.c # 2004/04/01 10:37:48-08:00 mludvig@suse.cz +1 -1 # [AF_KEY]: pfkey_send_new_mapping marks dest address incorrectly. # # ChangeSet # 2004/03/31 23:09:40-08:00 shemminger@osdl.org # [NET]: Mark lock_sock and release_sock as FASTCALL. # # net/core/sock.c # 2004/03/31 23:09:28-08:00 shemminger@osdl.org +2 -2 # [NET]: Mark lock_sock and release_sock as FASTCALL. # # include/net/sock.h # 2004/03/31 23:09:28-08:00 shemminger@osdl.org +2 -2 # [NET]: Mark lock_sock and release_sock as FASTCALL. # # ChangeSet # 2004/03/31 15:20:21-08:00 ahaas@airmail.net # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # ChangeSet # 2004/03/31 15:20:20-08:00 lxiep@ltcfwd.linux.ibm.com # [PATCH] kobject_set_name() doesn't allocate enough space # # lib/kobject.c # 2003/12/16 09:10:16-08:00 lxiep@ltcfwd.linux.ibm.com +3 -3 # kobject_set_name() doesn't allocate enough space # # drivers/video/tcx.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +53 -14 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/leo.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +66 -14 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/ffb.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +136 -28 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/cg6.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +41 -9 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/cg3.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +6 -2 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/cg14.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +76 -17 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # drivers/video/bw2.c # 2004/03/31 15:20:07-08:00 ahaas@airmail.net +4 -2 # [SPARC]: Add C99 initializers to Sparc frame buffer devices. # # ChangeSet # 2004/03/31 14:57:52-08:00 dsaxena@plexity.net # [PATCH] PCI: Allow arch-specific pci_set_dma_mask and friends # # The patch provides the ability for architectures to have custom # implementations of pci_set_dma_mask() and friends (dac_set_dma_mask # and set_consistent_dma_mask). The reason I need this is b/c I have # a chipset (Intel ARM IXP425) that has a broken PCI interface that # only allows PCI dma to/from the bottom 64MB of system memory. To get # around this limitation, I trap a custom dma-mapping implementation that # bounces buffers outside the 64MB window. At device discover time, my # custom platform_notify() function gets called and it sets the dma_mask # to (64MB-1) and in ARM's dma-mapping code, I check for dma_mask != 0xffffffff # and if that is true, I call the special bounce helpers. This works great # except that certain drivers (e100, ide-pci) call pci_set_dma_mask() # with 0xffffffff and the generic implementation only allows for the # architecture-defined pci_dma_supported() to return true or false. There # is no method for the architecture to tell the PCI layer "I can't set # the mask to 0xffffffff, but I can set it to this other value" and there # is no way to pass that back to the driver. What this means is that if # I have pci_set_dma_supported() return failure on full 32-bit DMA, the # driver will not initialize the card; however, if I return true, # pci_set_dma_mask() will set the dma mask to full 32-bits and I can no # longer trap and will have buffers that are not dma-able and cause # PCI master aborts. Both of those are not acceptable. IMHO, the # driver shouldn't care if the architecture has to bounce DMA outside of # 64MB and since this is not something most architectures have to worry # about, the easiest way to get around the issue is by allowing custom # pci_set_dma_mask() for arches that need it but keeping the generic # implementation for those that do not. In my case, it simply returns # 0 to the driver but keeps the device mask set to 64MB-1 so I can trap. # # drivers/pci/pci.c # 2004/03/26 08:58:01-08:00 dsaxena@plexity.net +5 -0 # PCI: Allow arch-specific pci_set_dma_mask and friends # # ChangeSet # 2004/03/31 14:55:47-08:00 johnrose@austin.ibm.com # [PATCH] PCI Hotplug: RPA PCI Hotplug - redundant free # # Please commit the following patch, which removes a redundant call to a # cleanup function from an error path of the module init code. # # drivers/pci/hotplug/rpaphp_pci.c # 2004/03/30 10:50:32-08:00 johnrose@austin.ibm.com +0 -1 # PCI Hotplug: RPA PCI Hotplug - redundant free # # ChangeSet # 2004/03/31 14:53:59-08:00 rddunlap@osdl.org # [PATCH] PCI: move DMA_nnBIT_MASK to linux/dma-mapping.h # # include/linux/pci.h # 2004/03/30 17:53:49-08:00 rddunlap@osdl.org +0 -3 # PCI: move DMA_nnBIT_MASK to linux/dma-mapping.h # # include/linux/dma-mapping.h # 2004/03/30 17:53:54-08:00 rddunlap@osdl.org +3 -0 # PCI: move DMA_nnBIT_MASK to linux/dma-mapping.h # # ChangeSet # 2004/03/31 14:05:58-08:00 davem@nuts.davemloft.net # [TG3]: Wait a bit for BMSR/BMCR bits to settle in PHY setup. # # drivers/net/tg3.c # 2004/03/31 14:05:42-08:00 davem@nuts.davemloft.net +18 -4 # [TG3]: Wait a bit for BMSR/BMCR bits to settle in PHY setup. # # ChangeSet # 2004/03/31 13:56:46-08:00 davem@nuts.davemloft.net # [TG3]: When link is down, set stats coalescing ticks to zero. # # drivers/net/tg3.c # 2004/03/31 13:56:30-08:00 davem@nuts.davemloft.net +7 -0 # [TG3]: When link is down, set stats coalescing ticks to zero. # # ChangeSet # 2004/03/31 13:50:19-08:00 davem@nuts.davemloft.net # [TG3]: Fix serdes cfg programming on 5704. # # drivers/net/tg3.c # 2004/03/31 13:50:01-08:00 davem@nuts.davemloft.net +11 -2 # [TG3]: Fix serdes cfg programming on 5704. # # ChangeSet # 2004/03/31 13:35:13-08:00 davem@nuts.davemloft.net # [TG3]: Set GRC_MISC_CFG prescaler more safely. # # drivers/net/tg3.c # 2004/03/31 13:34:56-08:00 davem@nuts.davemloft.net +4 -2 # [TG3]: Set GRC_MISC_CFG prescaler more safely. # # ChangeSet # 2004/03/31 13:31:13-08:00 davem@nuts.davemloft.net # [TG3]: Add missing 5704 BX workaround, and fix typo in autoneg fix. # # drivers/net/tg3.c # 2004/03/31 13:30:57-08:00 davem@nuts.davemloft.net +8 -1 # [TG3]: Add missing 5704 BX workaround, and fix typo in autoneg fix. # # ChangeSet # 2004/03/30 17:26:44-08:00 rddunlap@osdl.org # [PATCH] PCI: add DMA_{64,32}BIT constants # # On Tue, 23 Mar 2004 00:23:05 -0500 Jeff Garzik wrote: # >>Yeah well... in the intervening time, somebody on IRC commented # >> # >>"so what is so PCI-specific about those constants?" # >> # >>They probably ought to be DMA_{32,64}BIT_MASK or somesuch. # # Here's an updated patch, applies to 2.6.5-rc2-bk9. # I left the DMA_xxBIT_MASK defines in linux/pci.h, although # they aren't necessarily PCI-specific. Would we prefer to # have them in linux/dma-mapping.h ? # # include/linux/pci.h # 2004/03/29 21:57:18-08:00 rddunlap@osdl.org +3 -0 # PCI: add DMA_{64,32}BIT constants # # drivers/net/ixgb/ixgb_main.c # 2004/03/29 22:27:20-08:00 rddunlap@osdl.org +2 -2 # PCI: add DMA_{64,32}BIT constants # # drivers/net/ixgb/ixgb.h # 2004/03/29 21:57:18-08:00 rddunlap@osdl.org +0 -2 # PCI: add DMA_{64,32}BIT constants # # drivers/net/e1000/e1000_main.c # 2004/03/29 22:17:55-08:00 rddunlap@osdl.org +2 -2 # PCI: add DMA_{64,32}BIT constants # # drivers/net/e1000/e1000.h # 2004/03/29 21:57:18-08:00 rddunlap@osdl.org +0 -2 # PCI: add DMA_{64,32}BIT constants # # Documentation/DMA-mapping.txt # 2004/03/29 21:57:18-08:00 rddunlap@osdl.org +8 -8 # PCI: add DMA_{64,32}BIT constants # # ChangeSet # 2004/03/30 17:24:37-08:00 greg@kroah.com # Cset exclude: jgarzik@redhat.com|ChangeSet|20040323051558|61282 # # include/linux/pci.h # 2004/03/30 17:24:11-08:00 greg@kroah.com +0 -0 # Exclude # # drivers/net/ixgb/ixgb.h # 2004/03/30 17:24:11-08:00 greg@kroah.com +0 -0 # Exclude # # drivers/net/e1000/e1000.h # 2004/03/30 17:24:11-08:00 greg@kroah.com +0 -0 # Exclude # # Documentation/DMA-mapping.txt # 2004/03/30 17:24:11-08:00 greg@kroah.com +0 -0 # Exclude # # ChangeSet # 2004/03/29 20:24:54-08:00 laforge@netfilter.org # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv6/netfilter/Makefile # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +1 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv6/netfilter/Kconfig # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +12 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ipt_state.c # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +3 -1 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ipt_conntrack.c # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +7 -5 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ip_nat_core.c # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +4 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +52 -1 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +23 -9 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/Makefile # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +2 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/Kconfig # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +24 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # include/linux/netfilter_ipv4/ipt_state.h # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +2 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # include/linux/netfilter_ipv4/ipt_conntrack.h # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +1 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # include/linux/netfilter_ipv4/ip_conntrack.h # 2004/03/29 20:24:39-08:00 laforge@netfilter.org +3 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # include/linux/netfilter_ipv4.h # 2004/03/29 20:24:38-08:00 laforge@netfilter.org +2 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv6/netfilter/ip6table_raw.c # 2004/03/29 20:24:35-08:00 laforge@netfilter.org +154 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/iptable_raw.c # 2004/03/29 20:24:35-08:00 laforge@netfilter.org +149 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv6/netfilter/ip6table_raw.c # 2004/03/29 20:24:35-08:00 laforge@netfilter.org +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/net/ipv6/netfilter/ip6table_raw.c # # net/ipv4/netfilter/iptable_raw.c # 2004/03/29 20:24:35-08:00 laforge@netfilter.org +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/net/ipv4/netfilter/iptable_raw.c # # net/ipv4/netfilter/ipt_NOTRACK.c # 2004/03/29 20:24:34-08:00 laforge@netfilter.org +75 -0 # [NETFILTER]: Add 'raw' table, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ipt_NOTRACK.c # 2004/03/29 20:24:34-08:00 laforge@netfilter.org +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/net/ipv4/netfilter/ipt_NOTRACK.c # # ChangeSet # 2004/03/29 20:22:47-08:00 davem@nuts.davemloft.net # [NETFILTER]: Missed these files in nf_log commit. # # include/linux/netfilter_logging.h # 2004/03/29 20:22:30-08:00 davem@nuts.davemloft.net +33 -0 # [NETFILTER]: Missed these files in nf_log commit. # # include/linux/netfilter_ipv6/ip6_logging.h # 2004/03/29 20:22:30-08:00 davem@nuts.davemloft.net +20 -0 # [NETFILTER]: Missed these files in nf_log commit. # # include/linux/netfilter_logging.h # 2004/03/29 20:22:30-08:00 davem@nuts.davemloft.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/include/linux/netfilter_logging.h # # include/linux/netfilter_ipv6/ip6_logging.h # 2004/03/29 20:22:30-08:00 davem@nuts.davemloft.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/include/linux/netfilter_ipv6/ip6_logging.h # # include/linux/netfilter_ipv4/ip_logging.h # 2004/03/29 20:22:29-08:00 davem@nuts.davemloft.net +20 -0 # [NETFILTER]: Missed these files in nf_log commit. # # include/linux/netfilter_ipv4/ip_logging.h # 2004/03/29 20:22:29-08:00 davem@nuts.davemloft.net +0 -0 # BitKeeper file /disk1/BK/nf-2.6.6/include/linux/netfilter_ipv4/ip_logging.h # # ChangeSet # 2004/03/29 20:21:44-08:00 laforge@netfilter.org # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # net/ipv6/netfilter/ip6t_LOG.c # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +64 -23 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ipt_ULOG.c # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +57 -20 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # net/ipv4/netfilter/ipt_LOG.c # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +60 -20 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # net/core/netfilter.c # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +68 -0 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # include/linux/netfilter_ipv4/ipt_ULOG.h # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +3 -0 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # include/linux/netfilter.h # 2004/03/29 20:21:32-08:00 laforge@netfilter.org +18 -0 # [NETFILTER]: Add nf_log handler, from Jozsef Kadlecsik. # # ChangeSet # 2004/03/29 20:19:08-08:00 laforge@netfilter.org # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_tftp.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +14 -11 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_standalone.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +1 -0 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_irc.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +9 -5 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_ftp.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +12 -5 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +57 -37 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # net/ipv4/netfilter/ip_conntrack_amanda.c # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +25 -17 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # include/linux/netfilter_ipv4/ip_conntrack_helper.h # 2004/03/29 20:18:56-08:00 laforge@netfilter.org +6 -2 # [NETFILTER]: Cleanup conntrack helper API # # A: Pablo Neira # D: This patch changes the conntrack helper API. Rather than having the # D: helper allocate an expect on the stack and then have the core # D: kmalloc and memcpy, it is now the job of a helper to call # D: ip_conntrack_expect_alloc() # # ChangeSet # 2004/03/29 20:18:04-08:00 laforge@netfilter.org # [NETFILTER]: Locking optimization in ip_conntrack_core # # A: Pablo Neira # D: This patch puts tightens up a lock protected section in # D: ip_ct_refresh() # # net/ipv4/netfilter/ip_conntrack_core.c # 2004/03/29 20:17:52-08:00 laforge@netfilter.org +2 -2 # [NETFILTER]: Locking optimization in ip_conntrack_core # # A: Pablo Neira # D: This patch puts tightens up a lock protected section in # D: ip_ct_refresh() # # ChangeSet # 2004/03/29 20:17:20-08:00 laforge@netfilter.org # [NETFILTER]: Optimization of ip_conntrack_proto_tcp:tcp_packet() # # A: Pablo Neira # D: This patch cleans up tcp_packet(). No semantical change, just juggling # D: code pieces. # # net/ipv4/netfilter/ip_conntrack_proto_tcp.c # 2004/03/29 20:17:08-08:00 laforge@netfilter.org +21 -19 # [NETFILTER]: Optimization of ip_conntrack_proto_tcp:tcp_packet() # # A: Pablo Neira # D: This patch cleans up tcp_packet(). No semantical change, just juggling # D: code pieces. # # ChangeSet # 2004/03/29 15:11:50-08:00 davem@nuts.davemloft.net # [TG3]: Do not allow illegal ethtool advertisement bits. # # drivers/net/tg3.c # 2004/03/29 15:11:37-08:00 davem@nuts.davemloft.net +11 -0 # [TG3]: Do not allow illegal ethtool advertisement bits. # # ChangeSet # 2004/03/29 14:57:24-08:00 davem@nuts.davemloft.net # [TG3]: At start of tg3_phy_copper_begin, force phy out of loopback mode. # # drivers/net/tg3.c # 2004/03/29 14:57:11-08:00 davem@nuts.davemloft.net +2 -0 # [TG3]: At start of tg3_phy_copper_begin, force phy out of loopback mode. # # ChangeSet # 2004/03/29 11:43:53-08:00 davem@nuts.davemloft.net # [TG3]: Kill 'force' arg to tg3_phy_reset, it is always set. # # drivers/net/tg3.c # 2004/03/29 11:43:35-08:00 davem@nuts.davemloft.net +4 -10 # [TG3]: Kill 'force' arg to tg3_phy_reset, it is always set. # # ChangeSet # 2004/03/26 16:32:52-08:00 willy@debian.org # [PATCH] PCI Hotplug: Rewrite acpiphp detect_used_resource # # There are two unrelated problems in acpiphp that are fixed by this patch. # First, acpiphp can be a module, so it is unsafe to probe the BARs of each # device while it initialises -- the device may be active at the time. # Second, it does not know about PCI-PCI bridge registers and so it reads # garbage for the last 4 registers of the PCI-PCI bridge card and doesn't # take into account the ranges that are forwarded by the bridge. # # This patch avoids all that by using the struct resources embedded in # the pci_dev. Note that we no longer need to recurse as all the devices # on the other side of a PCI-PCI bridge have their resources entirely # contained within the PCI-PCI bridge's ranges. # # drivers/pci/hotplug/acpiphp_pci.c # 2004/03/22 14:43:00-08:00 willy@debian.org +26 -84 # PCI Hotplug: Rewrite acpiphp detect_used_resource # # ChangeSet # 2004/03/26 16:32:21-08:00 willy@debian.org # [PATCH] PCI Hotplug: Don't up() twice in acpiphp # # On the error path, we currently try to up() a semaphore twice. # There was also a typo in an error message. # # drivers/pci/hotplug/acpiphp_glue.c # 2004/03/22 14:43:10-08:00 willy@debian.org +18 -20 # PCI Hotplug: Don't up() twice in acpiphp # # ChangeSet # 2004/03/26 16:31:44-08:00 dlsy@snoqualmie.dp.intel.com # [PATCH] PCI: Updates for PCI Express hot-plug driver # # include/linux/pci_ids.h # 2004/03/22 11:14:28-08:00 dlsy@snoqualmie.dp.intel.com +1 -0 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/quirks.c # 2004/03/22 11:14:28-08:00 dlsy@snoqualmie.dp.intel.com +11 -0 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/pci.h # 2004/03/22 11:14:28-08:00 dlsy@snoqualmie.dp.intel.com +2 -0 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/hotplug/shpchprm_legacy.c # 2004/03/22 11:14:28-08:00 dlsy@snoqualmie.dp.intel.com +0 -30 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/hotplug/shpchprm_acpi.c # 2004/03/22 11:14:28-08:00 dlsy@snoqualmie.dp.intel.com +2 -1 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/hotplug/shpchp_hpc.c # 2004/03/22 11:14:24-08:00 dlsy@snoqualmie.dp.intel.com +5 -6 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/hotplug/pciehp_pci.c # 2004/03/22 11:16:13-08:00 dlsy@snoqualmie.dp.intel.com +0 -2 # PCI: Updates for PCI Express hot-plug driver # # drivers/pci/hotplug/pciehp_hpc.c # 2004/03/22 11:14:14-08:00 dlsy@snoqualmie.dp.intel.com +74 -17 # PCI: Updates for PCI Express hot-plug driver # # ChangeSet # 2004/03/26 16:24:34-08:00 greg@kroah.com # Merge bk://kernel.bkbits.net/jgarzik/pci-dma-mask-2.6 # into kroah.com:/home/greg/linux/BK/pci-2.6 # # include/linux/pci.h # 2004/03/26 16:24:30-08:00 greg@kroah.com +0 -0 # Auto merged # # Documentation/DMA-mapping.txt # 2004/03/26 16:24:30-08:00 greg@kroah.com +0 -0 # Auto merged # # ChangeSet # 2004/03/26 16:11:41-08:00 greg@kroah.com # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # include/linux/pci.h # 2004/03/26 08:11:04-08:00 greg@kroah.com +87 -12 # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # drivers/pci/proc.c # 2004/03/26 08:11:04-08:00 greg@kroah.com +13 -13 # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # drivers/pci/probe.c # 2004/03/26 08:11:04-08:00 greg@kroah.com +40 -0 # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # drivers/pci/pci.c # 2004/03/26 08:11:04-08:00 greg@kroah.com +50 -8 # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # drivers/pci/pci-sysfs.c # 2004/03/26 08:11:04-08:00 greg@kroah.com +22 -7 # PCI: add ability to access pci extended config space for PCI Express devices # # Patch originally written by Intel, cleaned up and made sane by # Matthew Wilcox and then tweaked a bit more by me. # # From Matt's original email: # - Add cfg_size to struct pci_dev. # - Use it in sysfs and procfs. # - Introduce pci_find_ext_capability() for finding extended capabilities. # - Change the PCI_X_STATUS defines to match the spec (mea culpa there). # - Add defines for the extended capabilities. # # ChangeSet # 2004/03/26 14:24:35-08:00 romain@lievin.net # [PATCH] tipar char driver (divide by zero) # # A patch about the tipar.c char driver has been sent on lkml by Sebastien # Bourdeau. It fixes a divide-by-zero error when we try to read/write data # after setting the timeout to 0. # # drivers/char/tipar.c # 2004/03/21 13:11:11-08:00 romain@lievin.net +11 -5 # tipar char driver (divide by zero) # # ChangeSet # 2004/03/25 10:44:05-08:00 hannal@us.ibm.com # [PATCH] added class support to istallion.c # # Here is a patch to add class support to the Stallion Intelligent multiport # serial driver. # # drivers/char/istallion.c # 2004/03/23 16:49:29-08:00 hannal@us.ibm.com +10 -1 # added class support to istallion.c # # ChangeSet # 2004/03/25 10:43:11-08:00 hannal@us.ibm.com # [PATCH] added class support to stallion.c # # Here is a patch to add class support to the Stallion multiport # serial driver. # # drivers/char/stallion.c # 2004/03/19 17:28:08-08:00 hannal@us.ibm.com +9 -1 # added class support to stallion.c # # ChangeSet # 2004/03/22 21:48:26-05:00 jgarzik@redhat.com # [MAINTAINERS] remove mention of defunct linux-via mailing list # # Noticed by Adrian Bunk. # # MAINTAINERS # 2004/03/22 21:48:21-05:00 jgarzik@redhat.com +1 -2 # [MAINTAINERS] remove mention of defunct linux-via mailing list # # Noticed by Adrian Bunk. # # ChangeSet # 2004/03/22 21:47:47-05:00 jgarzik@redhat.com # [BK] ignore build-generated files in scripts/basic/ and drivers/md/ # # BitKeeper/etc/ignore # 2004/03/22 21:45:35-05:00 jgarzik@redhat.com +10 -0 # Added drivers/md/mktables drivers/md/raid6int1.c drivers/md/raid6int16.c drivers/md/raid6int2.c drivers/md/raid6int32.c drivers/md/raid6int4.c drivers/md/raid6int8.c drivers/md/raid6tables.c scripts/basic/fixdep scripts/basic/split-include to the ignore list # # BitKeeper/etc/ignore # 2004/03/22 20:37:12-05:00 jgarzik@redhat.com +1 -0 # added scripts/basic/docproc # # ChangeSet # 2004/03/22 17:24:10-05:00 jgarzik@redhat.com # Remove mention of non-existent tulip.txt from Doc/netwrk/00-INDEX # # Documentation/networking/00-INDEX # 2004/03/22 17:22:05-05:00 jgarzik@redhat.com +0 -2 # Remove mention of non-existent tulip.txt from Doc/netwrk/00-INDEX # # ChangeSet # 2004/03/22 11:47:06-08:00 kronos@kronoz.cjb.net # [PATCH] Sysfs for framebuffer # # the following patch (against 2.6.5-rc2) teaches fb to use class_simple. # With this patch udev will automagically create device nodes for each # framebuffer registered. Once all drivers are converted to # framebuffer_{alloc,release} we can switch to our own class. # # This is what sysfs dir looks like: # # notebook:~# tree /sys/class/graphics/ # /sys/class/graphics/ # `-- fb0 # `-- dev # # drivers/video/fbmem.c # 2004/03/20 07:17:26-08:00 kronos@kronoz.cjb.net +19 -0 # Sysfs for framebuffer # # ChangeSet # 2004/03/19 16:39:37-08:00 hannal@us.ibm.com # [PATCH] add class support to floppy tape driver zftape-init.c # # Here is a patch to add class support to zftape-init.c: # # MODULE_DESCRIPTION(ZFTAPE_VERSION " - " # "VFS interface for the Linux floppy tape driver. " # "Support for QIC-113 compatible volume table " # "and builtin compression (lzrw3 algorithm)"); # # I have verified it compiles but do not have the hardware to test it. # # drivers/char/ftape/zftape/zftape-init.c # 2004/03/18 16:37:56-08:00 hannal@us.ibm.com +17 -0 # add class support to floppy tape driver zftape-init.c # # ChangeSet # 2004/03/19 16:39:16-08:00 hannal@us.ibm.com # [PATCH] QIC-02 tape drive hookup to classes in sysfs # # Here is a patch to hook up the qic02 tape device to have class # support in sysfs. I have verified it compiles. I do not have access to # the hardware to test. Could someone who does please verify? # # From the file: # * This is a driver for the Wangtek 5150 tape drive with # * a QIC-02 controller for ISA-PC type computers. # * Hopefully it will work with other QIC-02 tape drives as well. # # drivers/char/tpqic02.c # 2004/03/17 16:19:44-08:00 hannal@us.ibm.com +22 -0 # QIC-02 tape drive hookup to classes in sysfs # # ChangeSet # 2004/03/19 14:15:17-08:00 greg@kroah.com # Driver class: remove possible oops # # This happens when the device associated with a class device goes away before # the class does. # # drivers/base/class.c # 2004/03/19 06:14:46-08:00 greg@kroah.com +2 -4 # Driver class: remove possible oops # # This happens when the device associated with a class device goes away before # the class does. # # ChangeSet # 2004/03/19 13:12:46-08:00 greg@kroah.com # VC: fix bug in vty_init() where vcs_init() was not called early enough. # # It was being used before initialized, not nice :( # # drivers/char/vt.c # 2004/03/19 13:12:09-08:00 greg@kroah.com +2 -1 # VC: fix bug in vty_init() where vcs_init() was not called early enough. # # It was being used before initialized, not nice :( # # ChangeSet # 2004/03/19 13:10:22-08:00 greg@kroah.com # add sysfs support for vc devices. # # drivers/char/vc_screen.c # 2004/03/19 13:10:12-08:00 greg@kroah.com +10 -0 # add sysfs support for vc devices. # # ChangeSet # 2004/03/19 13:05:08-08:00 greg@kroah.com # Driver Core: fix spaces instead of tabs problem in the Kconfig file. # # drivers/base/Kconfig # 2004/03/19 13:05:01-08:00 greg@kroah.com +8 -8 # Driver Core: fix spaces instead of tabs problem in the Kconfig file. # # ChangeSet # 2004/03/18 20:48:58-08:00 davem@nuts.davemloft.net # [TG3]: Just completely delete the disabled FTQ reset code. # # drivers/net/tg3.c # 2004/03/18 20:48:42-08:00 davem@nuts.davemloft.net +0 -16 # [TG3]: Just completely delete the disabled FTQ reset code. # # ChangeSet # 2004/03/18 20:46:50-08:00 mchan@broadcom.com # [TG3]: Jumbo frames and FTQ reset patch. # # 1. Set extended packet length bit in phy register 0x18 shadow register 0 # on all chips that support jumbo frames (i.e. all chips except 5705 and # its variants). Jumbo frame reception is less reliable (more CRC errors) # if this bit is not set. This bit can be set regardless of the current # MTU setting. # # # 2. Remove FTQ reset during chip init. This is the best fix for the ASF # race condition problem that I mentioned a few months ago. The FTQ reset # is redundant as it is already reset during GRC reset. # # # drivers/net/tg3.c # 2004/03/18 20:43:42-08:00 mchan@broadcom.com +23 -3 # [TG3]: Jumbo frames and FTQ reset patch. # # 1. Set extended packet length bit in phy register 0x18 shadow register 0 # on all chips that support jumbo frames (i.e. all chips except 5705 and # its variants). Jumbo frame reception is less reliable (more CRC errors) # if this bit is not set. This bit can be set regardless of the current # MTU setting. # # # 2. Remove FTQ reset during chip init. This is the best fix for the ASF # race condition problem that I mentioned a few months ago. The FTQ reset # is redundant as it is already reset during GRC reset. # # # ChangeSet # 2004/03/16 09:12:05-05:00 bcollins@debian.org # Merge http://linux.bkbits.net/linux-2.5 # into debian.org:/usr/src/kernel/ieee1394-2.6 # # drivers/ieee1394/ohci1394.c # 2004/03/16 09:11:46-05:00 bcollins@debian.org +0 -0 # Auto merged # # ChangeSet # 2004/03/11 15:46:42-05:00 weihs@linux1394.org # IEEE1394/Lynx(r1182): Explicitly set LCtrl bit in phy register set. # # drivers/ieee1394/pcilynx.c # 2004/03/11 15:45:50-05:00 weihs@linux1394.org +3 -3 # Explicitly set LCtrl bit in phy register set. # # ChangeSet # 2004/03/11 15:44:40-05:00 kberg@linux1394.org # [IEEE1394/OHCI]: Deal with some OHCI implementations that have an invalid max_rec field. # # drivers/ieee1394/ohci1394.c # 2004/03/11 15:43:09-05:00 kberg@linux1394.org +33 -0 # Deal with some OHCI implementations that have an invalid max_rec field. # diff -Nru a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt --- a/Documentation/DMA-mapping.txt Sun Apr 18 13:42:41 2004 +++ b/Documentation/DMA-mapping.txt Sun Apr 18 13:42:41 2004 @@ -132,7 +132,7 @@ The standard 32-bit addressing PCI device would do something like this: - if (pci_set_dma_mask(pdev, 0xffffffff)) { + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "mydev: No suitable DMA available.\n"); goto ignore_this_device; @@ -151,9 +151,9 @@ int using_dac; - if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) { + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { using_dac = 1; - } else if (!pci_set_dma_mask(pdev, 0xffffffff)) { + } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { using_dac = 0; } else { printk(KERN_WARNING @@ -166,14 +166,14 @@ int using_dac, consistent_using_dac; - if (!pci_set_dma_mask(pdev, 0xffffffffffffffff)) { + if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { using_dac = 1; consistent_using_dac = 1; - pci_set_consistent_dma_mask(pdev, 0xffffffffffffffff) - } else if (!pci_set_dma_mask(pdev, 0xffffffff)) { + pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { using_dac = 0; consistent_using_dac = 0; - pci_set_consistent_dma_mask(pdev, 0xffffffff) + pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); } else { printk(KERN_WARNING "mydev: No suitable DMA available.\n"); @@ -215,7 +215,7 @@ Here is pseudo-code showing how this might be done: - #define PLAYBACK_ADDRESS_BITS 0xffffffff + #define PLAYBACK_ADDRESS_BITS DMA_32BIT_MASK #define RECORD_ADDRESS_BITS 0x00ffffff struct my_sound_card *card; diff -Nru a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX --- a/Documentation/networking/00-INDEX Sun Apr 18 13:42:41 2004 +++ b/Documentation/networking/00-INDEX Sun Apr 18 13:42:41 2004 @@ -111,8 +111,6 @@ - ThunderLAN (Compaq Netelligent 10/100, Olicom OC-2xxx) driver info. tms380tr.txt - SysKonnect Token Ring ISA/PCI adapter driver info. -tulip.txt - - info on using DEC 21040/21041/21140 based PCI Ethernet cards. tuntap.txt - TUN/TAP device driver, allowing user space Rx/Tx of packets. vortex.txt diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sun Apr 18 13:42:41 2004 +++ b/MAINTAINERS Sun Apr 18 13:42:41 2004 @@ -1061,23 +1061,33 @@ S: Maintained INTEL PRO/100 ETHERNET SUPPORT +P: John Ronciak +M: john.ronciak@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com P: Scott Feldman M: scott.feldman@intel.com +W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/1000 GIGABIT ETHERNET SUPPORT P: Jeb Cramer M: cramerj@intel.com -P: Scott Feldman -M: scott.feldman@intel.com +P: John Ronciak +M: john.ronciak@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/10GbE SUPPORT +P: Ayyappan Veeraiyan +M: ayyappan.veeraiyan@intel.com P: Ganesh Venkatesan -M: Ganesh.Venkatesan@intel.com -P: Scott Feldman -M: scott.feldman@intel.com +M: ganesh.venkatesan@intel.com +P: John Ronciak +M: john.ronciak@intel.com +W: http://sourceforge.net/projects/e1000/ S: Supported INTERMEZZO FILE SYSTEM @@ -2266,9 +2276,8 @@ L: linux-kernel@vger.kernel.org S: Maintained -VIA 82Cxxx AUDIO DRIVER +VIA 82Cxxx AUDIO DRIVER (old OSS driver) P: Jeff Garzik -L: linux-via@gtf.org S: Odd fixes VIA RHINE NETWORK DRIVER diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile Sun Apr 18 13:42:40 2004 +++ b/arch/arm/Makefile Sun Apr 18 13:42:40 2004 @@ -7,7 +7,7 @@ # # Copyright (C) 1995-2001 by Russell King -LDFLAGS_vmlinux :=-p -X +LDFLAGS_vmlinux :=-p --no-undefined -X LDFLAGS_BLOB :=--format binary AFLAGS_vmlinux.lds.o = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S diff -Nru a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile --- a/arch/arm/boot/compressed/Makefile Sun Apr 18 13:42:40 2004 +++ b/arch/arm/boot/compressed/Makefile Sun Apr 18 13:42:40 2004 @@ -66,7 +66,7 @@ EXTRA_CFLAGS := -fpic EXTRA_AFLAGS := -LDFLAGS_vmlinux := -p -X \ +LDFLAGS_vmlinux := -p --no-undefined -X \ $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) -T $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ diff -Nru a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c --- a/arch/arm/kernel/armksyms.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/kernel/armksyms.c Sun Apr 18 13:42:40 2004 @@ -73,8 +73,6 @@ * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. */ -extern void __do_softirq(void); - #define EXPORT_SYMBOL_ALIAS(sym,orig) \ const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) = \ @@ -88,7 +86,6 @@ EXPORT_SYMBOL_ALIAS(fp_printk,printk); EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig); -EXPORT_SYMBOL_NOVERS(__do_softirq); EXPORT_SYMBOL_NOVERS(__backtrace); /* platform dependent support */ diff -Nru a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c --- a/arch/arm/kernel/ptrace.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/kernel/ptrace.c Sun Apr 18 13:42:40 2004 @@ -526,7 +526,7 @@ * actually access the pt_regs stored on the kernel stack. */ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, - unsigned long *ret) + unsigned long __user *ret) { unsigned long tmp; @@ -559,7 +559,7 @@ /* * Get all user integer registers. */ -static int ptrace_getregs(struct task_struct *tsk, void *uregs) +static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) { struct pt_regs *regs = get_user_regs(tsk); @@ -569,7 +569,7 @@ /* * Set all user integer registers. */ -static int ptrace_setregs(struct task_struct *tsk, void *uregs) +static int ptrace_setregs(struct task_struct *tsk, void __user *uregs) { struct pt_regs newregs; int ret; @@ -591,7 +591,7 @@ /* * Get the child FPU state. */ -static int ptrace_getfpregs(struct task_struct *tsk, void *ufp) +static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp) { return copy_to_user(ufp, &tsk->thread_info->fpstate, sizeof(struct user_fp)) ? -EFAULT : 0; @@ -600,7 +600,7 @@ /* * Set the child FPU state. */ -static int ptrace_setfpregs(struct task_struct *tsk, void *ufp) +static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) { struct thread_info *thread = tsk->thread_info; thread->used_cp[1] = thread->used_cp[2] = 1; @@ -628,7 +628,7 @@ break; case PTRACE_PEEKUSR: - ret = ptrace_read_user(child, addr, (unsigned long *)data); + ret = ptrace_read_user(child, addr, (unsigned long __user *)data); break; /* @@ -704,19 +704,19 @@ break; case PTRACE_GETREGS: - ret = ptrace_getregs(child, (void *)data); + ret = ptrace_getregs(child, (void __user *)data); break; case PTRACE_SETREGS: - ret = ptrace_setregs(child, (void *)data); + ret = ptrace_setregs(child, (void __user *)data); break; case PTRACE_GETFPREGS: - ret = ptrace_getfpregs(child, (void *)data); + ret = ptrace_getfpregs(child, (void __user *)data); break; case PTRACE_SETFPREGS: - ret = ptrace_setfpregs(child, (void *)data); + ret = ptrace_setfpregs(child, (void __user *)data); break; default: diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c --- a/arch/arm/kernel/signal.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/kernel/signal.c Sun Apr 18 13:42:40 2004 @@ -76,7 +76,7 @@ } asmlinkage int -sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs) +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) { sigset_t saveset, newset; @@ -104,8 +104,8 @@ } asmlinkage int -sys_sigaction(int sig, const struct old_sigaction *act, - struct old_sigaction *oact) +sys_sigaction(int sig, const struct old_sigaction __user *act, + struct old_sigaction __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -147,15 +147,15 @@ struct rt_sigframe { - struct siginfo *pinfo; - void *puc; + struct siginfo __user *pinfo; + void __user *puc; struct siginfo info; struct ucontext uc; unsigned long retcode; }; static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { int err = 0; @@ -184,7 +184,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) { - struct sigframe *frame; + struct sigframe __user *frame; sigset_t set; /* Always make any pending restarted system calls return -EINTR */ @@ -198,7 +198,7 @@ if (regs->ARM_sp & 7) goto badframe; - frame = (struct sigframe *)regs->ARM_sp; + frame = (struct sigframe __user *)regs->ARM_sp; if (verify_area(VERIFY_READ, frame, sizeof (*frame))) goto badframe; @@ -232,7 +232,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) { - struct rt_sigframe *frame; + struct rt_sigframe __user *frame; sigset_t set; /* Always make any pending restarted system calls return -EINTR */ @@ -246,7 +246,7 @@ if (regs->ARM_sp & 7) goto badframe; - frame = (struct rt_sigframe *)regs->ARM_sp; + frame = (struct rt_sigframe __user *)regs->ARM_sp; if (verify_area(VERIFY_READ, frame, sizeof (*frame))) goto badframe; @@ -276,7 +276,7 @@ } static int -setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/ +setup_sigcontext(struct sigcontext __user *sc, /*struct _fpstate *fpstate,*/ struct pt_regs *regs, unsigned long mask) { int err = 0; @@ -307,7 +307,7 @@ return err; } -static inline void * +static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize) { unsigned long sp = regs->ARM_sp; @@ -321,12 +321,12 @@ /* * ATPCS B01 mandates 8-byte alignment */ - return (void *)((sp - framesize) & ~7); + return (void __user *)((sp - framesize) & ~7); } static int setup_return(struct pt_regs *regs, struct k_sigaction *ka, - unsigned long *rc, void *frame, int usig) + unsigned long __user *rc, void __user *frame, int usig) { unsigned long handler = (unsigned long)ka->sa.sa_handler; unsigned long retcode; @@ -387,7 +387,7 @@ static int setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) { - struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame)); + struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); int err = 0; if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) @@ -410,7 +410,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { - struct rt_sigframe *frame = get_sigframe(ka, regs, sizeof(*frame)); + struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); int err = 0; if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) diff -Nru a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c --- a/arch/arm/kernel/sys_arm.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/kernel/sys_arm.c Sun Apr 18 13:42:40 2004 @@ -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 int sys_pipe(unsigned long * fildes) +asmlinkage int sys_pipe(unsigned long __user *fildes) { int fd[2]; int error; @@ -94,7 +94,7 @@ unsigned long offset; }; -asmlinkage int old_mmap(struct mmap_arg_struct *arg) +asmlinkage int old_mmap(struct mmap_arg_struct __user *arg) { int error = -EFAULT; struct mmap_arg_struct a; @@ -141,11 +141,11 @@ struct sel_arg_struct { unsigned long n; - fd_set *inp, *outp, *exp; - struct timeval *tvp; + fd_set __user *inp, *outp, *exp; + struct timeval __user *tvp; }; -asmlinkage int old_select(struct sel_arg_struct *arg) +asmlinkage int old_select(struct sel_arg_struct __user *arg) { struct sel_arg_struct a; @@ -160,7 +160,8 @@ * * This is really horribly ugly. */ -asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) +asmlinkage int sys_ipc(uint call, int first, int second, int third, + void __user *ptr, long fifth) { int version, ret; @@ -169,28 +170,28 @@ switch (call) { case SEMOP: - return sys_semop (first, (struct sembuf *)ptr, second); + return sys_semop(first, (struct sembuf __user *)ptr, second); 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 **) ptr)) return -EFAULT; return sys_semctl (first, second, third, fourth); } case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, - second, third); + return sys_msgsnd(first, (struct msgbuf __user *) ptr, + second, third); case MSGRCV: switch (version) { case 0: { struct ipc_kludge tmp; if (!ptr) return -EINVAL; - if (copy_from_user(&tmp,(struct ipc_kludge *) ptr, + if (copy_from_user(&tmp,(struct ipc_kludge __user *)ptr, sizeof (tmp))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, second, @@ -198,36 +199,36 @@ } default: return sys_msgrcv (first, - (struct msgbuf *) ptr, + (struct msgbuf __user *) ptr, second, fifth, third); } 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: switch (version) { default: { 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); } case 1: /* iBCS2 emulator entry point */ if (!segment_eq(get_fs(), get_ds())) return -EINVAL; - return do_shmat (first, (char *) ptr, - second, (ulong *) third); + return do_shmat(first, (char __user *) ptr, + second, (ulong __user *) third); } case SHMDT: - return sys_shmdt ((char *)ptr); + 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; } @@ -266,7 +267,8 @@ /* sys_execve() executes a new program. * This is called indirectly via a small wrapper */ -asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_regs *regs) +asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv, + char __user * __user *envp, struct pt_regs *regs) { int error; char * filename; diff -Nru a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c --- a/arch/arm/mm/alignment.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/mm/alignment.c Sun Apr 18 13:42:40 2004 @@ -112,10 +112,10 @@ return len; } -static int proc_alignment_write(struct file *file, const char *buffer, +static int proc_alignment_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { - int mode; + char mode; if (count > 0) { if (get_user(mode, buffer)) diff -Nru a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c --- a/arch/arm/mm/fault-armv.c Sun Apr 18 13:42:40 2004 +++ b/arch/arm/mm/fault-armv.c Sun Apr 18 13:42:40 2004 @@ -186,19 +186,20 @@ void __flush_dcache_page(struct page *page) { + struct address_space *mapping = page_mapping(page); struct mm_struct *mm = current->active_mm; struct list_head *l; __cpuc_flush_dcache_page(page_address(page)); - if (!page_mapping(page)) + if (!mapping) return; /* * With a VIVT cache, we need to also write back * and invalidate any user data. */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each(l, &mapping->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; @@ -224,11 +225,15 @@ static void make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty) { + struct address_space *mapping = page_mapping(page); struct list_head *l; struct mm_struct *mm = vma->vm_mm; unsigned long pgoff; int aliases = 0; + if (!mapping) + return; + pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); /* @@ -236,7 +241,7 @@ * space, then we need to handle them specially to maintain * cache coherency. */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each(l, &mapping->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; diff -Nru a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types --- a/arch/arm/tools/mach-types Sun Apr 18 13:42:41 2004 +++ b/arch/arm/tools/mach-types Sun Apr 18 13:42:41 2004 @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Sat Mar 13 14:36:30 2004 +# Last update: Thu Apr 15 10:14:37 2004 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -390,9 +390,9 @@ mp1x ARCH_MP1X MP1X 379 at91rm9200tb ARCH_AT91RM9200TB AT91RM9200TB 380 adsvgx ARCH_ADSVGX ADSVGX 381 -omap1610 ARCH_OMAP1610 OMAP1610 382 +omap_h2 ARCH_OMAP_H2 OMAP_H2 382 pelee ARCH_PELEE PELEE 383 -e7xx ARCH_E7XX E7XX 384 +e740 MACH_E740 E740 384 iq80331 ARCH_IQ80331 IQ80331 385 versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387 kev7a400 MACH_KEV7A400 KEV7A400 388 @@ -485,3 +485,41 @@ vr1000 MACH_VR1000 VR1000 475 deisterpxa MACH_DEISTERPXA DEISTERPXA 476 bcm1160 MACH_BCM1160 BCM1160 477 +pcm022 MACH_PCM022 PCM022 478 +adsgcx MACH_ADSGCX ADSGCX 479 +dreadnaught MACH_DREADNAUGHT DREADNAUGHT 480 +dm320 MACH_DM320 DM320 481 +markov MACH_MARKOV MARKOV 482 +cos7a400 MACH_COS7A400 COS7A400 483 +milano MACH_MILANO MILANO 484 +ue9328 MACH_UE9328 UE9328 485 +uex255 MACH_UEX255 UEX255 486 +ue2410 MACH_UE2410 UE2410 487 +a620 MACH_A620 A620 488 +ocelot MACH_OCELOT OCELOT 489 +cheetah MACH_CHEETAH CHEETAH 490 +omap_perseus2 MACH_OMAP_PERSEUS2 OMAP_PERSEUS2 491 +zvue MACH_ZVUE ZVUE 492 +roverp1 MACH_ROVERP1 ROVERP1 493 +asidial2 MACH_ASIDIAL2 ASIDIAL2 494 +s3c24a0 MACH_S3C24A0 S3C24A0 495 +e800 MACH_E800 E800 496 +e750 MACH_E750 E750 497 +s3c5500 MACH_S3C5500 S3C5500 498 +smdk5500 MACH_SMDK5500 SMDK5500 499 +signalsync MACH_SIGNALSYNC SIGNALSYNC 500 +nbc MACH_NBC NBC 501 +er4525 MACH_ER4525 ER4525 502 +netbookpro MACH_NETBOOKPRO NETBOOKPRO 503 +hw90200 MACH_HW90200 HW90200 504 +condor MACH_CONDOR CONDOR 505 +cup MACH_CUP CUP 506 +kite MACH_KITE KITE 507 +scb9328 MACH_SCB9328 SCB9328 508 +omap_h3 MACH_OMAP_H3 OMAP_H3 509 +omap_h4 MACH_OMAP_H4 OMAP_H4 510 +n10 MACH_N10 N10 511 +montajade MACH_MONTAJADE MONTAJADE 512 +sg560 MACH_SG560 SG560 513 +dp1000 MACH_DP1000 DP1000 514 +omap_osk MACH_OMAP_OSK OMAP_OSK 515 diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Sun Apr 18 13:42:40 2004 +++ b/arch/i386/Kconfig Sun Apr 18 13:42:40 2004 @@ -1095,25 +1095,6 @@ select ACPI_BOOT default y -config PCI_USE_VECTOR - bool "Vector-based interrupt indexing (MSI)" - depends on X86_LOCAL_APIC && X86_IO_APIC - default n - help - This replaces the current existing IRQ-based index interrupt scheme - with the vector-base index scheme. The advantages of vector base - over IRQ base are listed below: - 1) Support MSI implementation. - 2) Support future IOxAPIC hotplug - - Note that this allows the device drivers to enable MSI, Message - Signaled Interrupt, on all MSI capable device functions detected. - Message Signal Interrupt enables an MSI-capable hardware device to - send an inbound Memory Write on its PCI bus instead of asserting - IRQ signal on device IRQ pin. - - If you don't know what to do here, say N. - source "drivers/pci/Kconfig" config ISA @@ -1339,6 +1320,12 @@ config X86_TRAMPOLINE bool depends on X86_SMP || (X86_VOYAGER && SMP) + default y + +# std_resources is overridden for pc9800, but that's not +# a currently selectable arch choice +config X86_STD_RESOURCES + bool default y config PC diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Sun Apr 18 13:42:40 2004 +++ b/arch/i386/kernel/Makefile Sun Apr 18 13:42:40 2004 @@ -31,6 +31,7 @@ obj-$(CONFIG_HPET_TIMER) += time_hpet.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o +obj-$(CONFIG_X86_STD_RESOURCES) += std_resources.o EXTRA_AFLAGS := -traditional diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c --- a/arch/i386/kernel/i8259.c Sun Apr 18 13:42:41 2004 +++ b/arch/i386/kernel/i8259.c Sun Apr 18 13:42:41 2004 @@ -445,6 +445,5 @@ if (boot_cpu_data.hard_math && !cpu_has_fpu) setup_irq(FPU_IRQ, &fpu_irq); - current_thread_info()->cpu = 0; - irq_ctx_init(0); + irq_ctx_init(current_thread_info()->cpu); } diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c --- a/arch/i386/kernel/nmi.c Sun Apr 18 13:42:41 2004 +++ b/arch/i386/kernel/nmi.c Sun Apr 18 13:42:41 2004 @@ -458,6 +458,13 @@ wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0, 0); apic_write(APIC_LVTPC, APIC_DM_NMI); } + else if (nmi_perfctr_msr == MSR_P6_PERFCTR0) { + /* Only P6 based Pentium M need to re-unmask + * the apic vector but it doesn't hurt + * other P6 variant */ + apic_write(APIC_LVTPC, + apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); + } wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); } } diff -Nru a/arch/i386/kernel/std_resources.c b/arch/i386/kernel/std_resources.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/std_resources.c Sun Apr 18 13:42:41 2004 @@ -0,0 +1,204 @@ +/* + * Machine specific resource allocation for generic. + */ + +#include +#include +#include + +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) + +static struct resource system_rom_resource = { + .name = "System ROM", + .start = 0xf0000, + .end = 0xfffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource extension_rom_resource = { + .name = "Extension ROM", + .start = 0xe0000, + .end = 0xeffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource adapter_rom_resources[] = { { + .name = "Adapter ROM", + .start = 0xc8000, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +} }; + +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + +static struct resource video_rom_resource = { + .name = "Video ROM", + .start = 0xc0000, + .end = 0xc7fff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource vram_resource = { + .name = "Video RAM area", + .start = 0xa0000, + .end = 0xbffff, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource standard_io_resources[] = { { + .name = "dma1", + .start = 0x0000, + .end = 0x001f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic1", + .start = 0x0020, + .end = 0x0021, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer", + .start = 0x0040, + .end = 0x005f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "keyboard", + .start = 0x0060, + .end = 0x006f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma page reg", + .start = 0x0080, + .end = 0x008f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic2", + .start = 0x00a0, + .end = 0x00a1, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma2", + .start = 0x00c0, + .end = 0x00df, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "fpu", + .start = 0x00f0, + .end = 0x00ff, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +} }; + +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + +static int __init checksum(unsigned char *rom, unsigned long length) +{ + unsigned char *p, sum = 0; + + for (p = rom; p < rom + length; p++) + sum += *p; + return sum == 0; +} + +void __init probe_roms(void) +{ + unsigned long start, length, upper; + unsigned char *rom; + int i; + + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + video_rom_resource.start = start; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* if checksum okay, trust length byte */ + if (length && checksum(rom, length)) + video_rom_resource.end = start + length - 1; + + request_resource(&iomem_resource, &video_rom_resource); + break; + } + + start = (video_rom_resource.end + 1 + 2047) & ~2047UL; + if (start < upper) + start = upper; + + /* system rom */ + request_resource(&iomem_resource, &system_rom_resource); + upper = system_rom_resource.start; + + /* check for extension rom (ignore length byte!) */ + rom = isa_bus_to_virt(extension_rom_resource.start); + if (romsignature(rom)) { + length = extension_rom_resource.end - extension_rom_resource.start + 1; + if (checksum(rom, length)) { + request_resource(&iomem_resource, &extension_rom_resource); + upper = extension_rom_resource.start; + } + } + + /* check for adapter roms on 2k boundaries */ + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* but accept any length that fits if checksum okay */ + if (!length || start + length > upper || !checksum(rom, length)) + continue; + + adapter_rom_resources[i].start = start; + adapter_rom_resources[i].end = start + length - 1; + request_resource(&iomem_resource, &adapter_rom_resources[i]); + + start = adapter_rom_resources[i++].end & ~2047UL; + } +} + +void __init request_graphics_resource(void) +{ + request_resource(&iomem_resource, &vram_resource); +} + +void __init request_standard_io_resources(void) +{ + int i; + + for (i = 0; i < STANDARD_IO_RESOURCES; i++) + request_resource(&ioport_resource, &standard_io_resources[i]); +} diff -Nru a/arch/i386/mach-default/Makefile b/arch/i386/mach-default/Makefile --- a/arch/i386/mach-default/Makefile Sun Apr 18 13:42:40 2004 +++ b/arch/i386/mach-default/Makefile Sun Apr 18 13:42:40 2004 @@ -2,4 +2,4 @@ # Makefile for the linux kernel. # -obj-y := setup.o topology.o std_resources.o +obj-y := setup.o topology.o diff -Nru a/arch/i386/mach-default/std_resources.c b/arch/i386/mach-default/std_resources.c --- a/arch/i386/mach-default/std_resources.c Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,204 +0,0 @@ -/* - * Machine specific resource allocation for generic. - */ - -#include -#include -#include - -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -#define ADAPTER_ROM_RESOURCES \ - (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource vram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer", - .start = 0x0040, - .end = 0x005f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x006f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - -#define STANDARD_IO_RESOURCES \ - (sizeof standard_io_resources / sizeof standard_io_resources[0]) - -static int __init checksum(unsigned char *rom, unsigned long length) -{ - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; -} - -void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && checksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (checksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !checksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -void __init request_graphics_resource(void) -{ - request_resource(&iomem_resource, &vram_resource); -} - -void __init request_standard_io_resources(void) -{ - int i; - - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, &standard_io_resources[i]); -} diff -Nru a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c --- a/arch/i386/mach-visws/mpparse.c Sun Apr 18 13:42:40 2004 +++ b/arch/i386/mach-visws/mpparse.c Sun Apr 18 13:42:40 2004 @@ -28,6 +28,7 @@ /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map; +unsigned int __initdata maxcpus = NR_CPUS; /* * The Visual Workstation is Intel MP compliant in the hardware @@ -88,6 +89,9 @@ ncpus = CO_CPU_MAX; } + + if (ncpus > maxcpus) + ncpus = maxcpus; smp_found_config = 1; while (ncpus--) diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c --- a/arch/i386/mach-voyager/voyager_smp.c Sun Apr 18 13:42:40 2004 +++ b/arch/i386/mach-voyager/voyager_smp.c Sun Apr 18 13:42:40 2004 @@ -599,12 +599,10 @@ idle->thread.eip = (unsigned long) start_secondary; unhash_process(idle); /* init_tasks (in sched.c) is indexed logically */ -#if 0 - // for AC kernels - stack_start.esp = (THREAD_SIZE + (__u8 *)TSK_TO_KSTACK(idle)); -#else - stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle->thread_info); -#endif + stack_start.esp = (void *) idle->thread.esp; + + irq_ctx_init(cpu); + /* Note: Don't modify initial ss override */ VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, (unsigned long)hijack_source.val, hijack_source.idt.Segment, diff -Nru a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c --- a/arch/i386/mach-voyager/voyager_thread.c Sun Apr 18 13:42:41 2004 +++ b/arch/i386/mach-voyager/voyager_thread.c Sun Apr 18 13:42:41 2004 @@ -135,7 +135,7 @@ init_timer(&wakeup_timer); sigfillset(¤t->blocked); - current->tty = NULL; /* get rid of controlling tty */ + current->signal->tty = NULL; printk(KERN_NOTICE "Voyager starting monitor thread\n"); diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c --- a/arch/i386/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 +++ b/arch/i386/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 @@ -206,10 +206,8 @@ struct page *page; page = pte_page(*(pte_t *)pmd); - if (page) { + if (page) page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT); - get_page(page); - } return page; } #endif diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Sun Apr 18 13:42:41 2004 +++ b/arch/ia64/Kconfig Sun Apr 18 13:42:41 2004 @@ -361,16 +361,6 @@ information about which PCI hardware does work under Linux and which doesn't. -config PCI_USE_VECTOR - bool - default y if IA64 - help - This enables MSI, Message Signaled Interrupt, on specific - MSI capable device functions detected upon requests from the - device drivers. Message Signal Interrupt enables an MSI-capable - hardware device to send an inbound Memory Write on its PCI bus - instead of asserting IRQ signal on device IRQ pin. - config PCI_DOMAINS bool default PCI diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c --- a/arch/ia64/ia32/ia32_signal.c Sun Apr 18 13:42:40 2004 +++ b/arch/ia64/ia32/ia32_signal.c Sun Apr 18 13:42:40 2004 @@ -114,8 +114,8 @@ err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); err |= __get_user(to->si_int, &from->si_int); diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c --- a/arch/ia64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 +++ b/arch/ia64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 @@ -170,7 +170,6 @@ ptep = huge_pte_offset(mm, addr); page = pte_page(*ptep); page += ((addr & ~HPAGE_MASK) >> PAGE_SHIFT); - get_page(page); return page; } int pmd_huge(pmd_t pmd) diff -Nru a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c --- a/arch/mips/kernel/signal32.c Sun Apr 18 13:42:41 2004 +++ b/arch/mips/kernel/signal32.c Sun Apr 18 13:42:41 2004 @@ -358,8 +358,8 @@ err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); diff -Nru a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c --- a/arch/mips/mm/cache.c Sun Apr 18 13:42:40 2004 +++ b/arch/mips/mm/cache.c Sun Apr 18 13:42:40 2004 @@ -55,9 +55,10 @@ void flush_dcache_page(struct page *page) { + struct address_space *mapping = page_mapping(page); unsigned long addr; - if (page_mapping(page) && !mapping_mapped(page->mapping)) { + if (mapping && !mapping_mapped(mapping)) { SetPageDcacheDirty(page); return; } diff -Nru a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c --- a/arch/parisc/kernel/cache.c Sun Apr 18 13:42:41 2004 +++ b/arch/parisc/kernel/cache.c Sun Apr 18 13:42:41 2004 @@ -229,16 +229,17 @@ void __flush_dcache_page(struct page *page) { + struct address_space *mapping = page_mapping(page); struct mm_struct *mm = current->active_mm; struct list_head *l; flush_kernel_dcache_page(page_address(page)); - if (!page_mapping(page)) + if (!mapping) return; /* check shared list first if it's not empty...it's usually * the shortest */ - list_for_each(l, &page->mapping->i_mmap_shared) { + list_for_each(l, &mapping->i_mmap_shared) { struct vm_area_struct *mpnt; unsigned long off; @@ -267,7 +268,7 @@ /* then check private mapping list for read only shared mappings * which are flagged by VM_MAYSHARE */ - list_for_each(l, &page->mapping->i_mmap) { + list_for_each(l, &mapping->i_mmap) { struct vm_area_struct *mpnt; unsigned long off; diff -Nru a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig --- a/arch/ppc64/configs/g5_defconfig Sun Apr 18 13:42:40 2004 +++ b/arch/ppc64/configs/g5_defconfig Sun Apr 18 13:42:40 2004 @@ -23,8 +23,10 @@ # CONFIG_SWAP=y 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=17 CONFIG_HOTPLUG=y # CONFIG_IKCONFIG is not set @@ -35,6 +37,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 # @@ -58,11 +61,11 @@ CONFIG_PPC_OF=y CONFIG_ALTIVEC=y CONFIG_PPC_PMAC=y -# CONFIG_PMAC_DART is not set +CONFIG_PMAC_DART=y CONFIG_PPC_PMAC64=y CONFIG_BOOTX_TEXT=y CONFIG_POWER4_ONLY=y -# CONFIG_IOMMU_VMERGE is not set +CONFIG_IOMMU_VMERGE=y CONFIG_SMP=y CONFIG_IRQ_ALL_CPUS=y CONFIG_NR_CPUS=2 @@ -80,6 +83,7 @@ # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG_CPU is not set # # PCMCIA/CardBus support @@ -224,7 +228,7 @@ # # SCSI Transport Attributes # -# CONFIG_SCSI_SPI_ATTRS is not set +CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set # @@ -242,6 +246,8 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_ATA_PIIX is not set # CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set # CONFIG_SCSI_SATA_VIA is not set # CONFIG_SCSI_SATA_VITESSE is not set # CONFIG_SCSI_BUSLOGIC is not set @@ -359,7 +365,6 @@ # CONFIG_NET_IPGRE is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m @@ -431,7 +436,6 @@ # # SCTP Configuration (EXPERIMENTAL) # -CONFIG_IPV6_SCTP__=y # CONFIG_IP_SCTP is not set # CONFIG_ATM is not set # CONFIG_VLAN_8021Q is not set @@ -498,7 +502,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=m @@ -506,6 +509,7 @@ # Ethernet (10000 Mbit) # # CONFIG_IXGB is not set +# CONFIG_S2IO is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_IBMVETH is not set @@ -675,6 +679,7 @@ # I2C Hardware Bus support # # CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set @@ -719,6 +724,8 @@ # Other I2C Chip support # # CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -811,6 +818,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=y # CONFIG_USB_UHCI_HCD is not set @@ -951,6 +959,7 @@ # 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_TEST is not set # @@ -1003,6 +1012,7 @@ # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y # CONFIG_DEVFS_FS is not set CONFIG_DEVPTS_FS_XATTR=y # CONFIG_DEVPTS_FS_SECURITY is not set @@ -1157,9 +1167,9 @@ CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m -# CONFIG_CRYPTO_ARC4 is not set +CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_TEST=m # diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S --- a/arch/ppc64/kernel/entry.S Sun Apr 18 13:42:40 2004 +++ b/arch/ppc64/kernel/entry.S Sun Apr 18 13:42:40 2004 @@ -487,7 +487,7 @@ mflr r0 std r0,16(r1) stdu r1,-RTAS_FRAME_SIZE(r1) /* Save SP and create stack space. */ - + /* Because RTAS is running in 32b mode, it clobbers the high order half * of all registers that it saves. We therefore save those registers * RTAS might touch to the stack. (r0, r3-r13 are caller saved) @@ -512,12 +512,25 @@ mfsrr1 r10 std r10,_SRR1(r1) + /* There is no way it is acceptable to get here with interrupts enabled, + * check it with the asm equivalent of WARN_ON + */ + mfmsr r6 + andi. r0,r6,MSR_EE +1: tdnei r0,0 +.section __bug_table,"a" + .llong 1b,__LINE__ + 0x1000000, 1f, 2f +.previous +.section .rodata,"a" +1: .asciz __FILE__ +2: .asciz "enter_rtas" +.previous + /* Unfortunately, the stack pointer and the MSR are also clobbered, * so they are saved in the PACA which allows us to restore * our original state after RTAS returns. */ std r1,PACAR1(r13) - mfmsr r6 std r6,PACASAVEDMSR(r13) /* Setup our real return addr */ diff -Nru a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S --- a/arch/ppc64/kernel/head.S Sun Apr 18 13:42:41 2004 +++ b/arch/ppc64/kernel/head.S Sun Apr 18 13:42:41 2004 @@ -93,8 +93,13 @@ _stext: #ifdef CONFIG_PPC_PSERIES _STATIC(__start) + /* NOP this out unconditionally */ +BEGIN_FTR_SECTION b .__start_initialization_pSeries +END_FTR_SECTION(0, 1) #endif + /* Catch branch to 0 in real mode */ + trap #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c --- a/arch/ppc64/kernel/prom.c Sun Apr 18 13:42:41 2004 +++ b/arch/ppc64/kernel/prom.c Sun Apr 18 13:42:41 2004 @@ -1926,6 +1926,11 @@ np->name = get_property(np, "name", 0); np->type = get_property(np, "device_type", 0); + if (!np->name) + np->name = ""; + if (!np->type) + np->type = ""; + /* get the device addresses and interrupts */ if (ifunc != NULL) mem_start = ifunc(np, mem_start, naddrc, nsizec); diff -Nru a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c --- a/arch/ppc64/kernel/rtas.c Sun Apr 18 13:42:40 2004 +++ b/arch/ppc64/kernel/rtas.c Sun Apr 18 13:42:40 2004 @@ -68,15 +68,20 @@ void call_rtas_display_status(char c) { - struct rtas_args *rtas = &(get_paca()->xRtas); + struct rtas_args *args = &(get_paca()->xRtas); + unsigned long s; + + spin_lock_irqsave(&rtas.lock, s); - rtas->token = 10; - rtas->nargs = 1; - rtas->nret = 1; - rtas->rets = (rtas_arg_t *)&(rtas->args[1]); - rtas->args[0] = (int)c; + args->token = 10; + args->nargs = 1; + args->nret = 1; + args->rets = (rtas_arg_t *)&(args->args[1]); + args->args[0] = (int)c; - enter_rtas((void *)__pa((unsigned long)rtas)); + enter_rtas((void *)__pa((unsigned long)args)); + + spin_unlock_irqrestore(&rtas.lock, s); } int @@ -91,8 +96,9 @@ return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; } -void -log_rtas_error(struct rtas_args *rtas_args) + +static int +__log_rtas_error(struct rtas_args *rtas_args) { struct rtas_args err_args, temp_args; @@ -111,13 +117,24 @@ PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", (void *)__pa((unsigned long)&err_args)); enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas)); - PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); - + PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); err_args = get_paca()->xRtas; get_paca()->xRtas = temp_args; - if (err_args.rets[0] == 0) + return err_args.rets[0]; +} + +void +log_rtas_error(struct rtas_args *rtas_args) +{ + unsigned long s; + int rc; + + spin_lock_irqsave(&rtas.lock, s); + rc = __log_rtas_error(rtas_args); + spin_unlock_irqrestore(&rtas.lock, s); + if (rc == 0) log_error(rtas_err_buf, ERR_TYPE_RTAS_LOG, 0); } @@ -126,9 +143,10 @@ unsigned long *outputs, ...) { va_list list; - int i; + int i, logit = 0; unsigned long s; struct rtas_args *rtas_args = &(get_paca()->xRtas); + long ret; PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n"); PPCDBG(PPCDBG_RTAS, "\ttoken = 0x%x\n", token); @@ -138,6 +156,9 @@ if (token == RTAS_UNKNOWN_SERVICE) return -1; + /* Gotta do something different here, use global lock for now... */ + spin_lock_irqsave(&rtas.lock, s); + rtas_args->token = token; rtas_args->nargs = nargs; rtas_args->nret = nret; @@ -150,26 +171,16 @@ va_end(list); for (i = 0; i < nret; ++i) - rtas_args->rets[i] = 0; + rtas_args->rets[i] = 0; -#if 0 /* Gotta do something different here, use global lock for now... */ - spin_lock_irqsave(&rtas_args->lock, s); -#else - spin_lock_irqsave(&rtas.lock, s); -#endif PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", (void *)__pa((unsigned long)rtas_args)); enter_rtas((void *)__pa((unsigned long)rtas_args)); PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n"); if (rtas_args->rets[0] == -1) - log_rtas_error(rtas_args); + logit = (__log_rtas_error(rtas_args) == 0); -#if 0 /* Gotta do something different here, use global lock for now... */ - spin_unlock_irqrestore(&rtas_args->lock, s); -#else - spin_unlock_irqrestore(&rtas.lock, s); -#endif ifppcdebug(PPCDBG_RTAS) { for(i=0; i < nret ;i++) udbg_printf("\tnret[%d] = 0x%lx\n", i, (ulong)rtas_args->rets[i]); @@ -178,7 +189,15 @@ if (nret > 1 && outputs != NULL) for (i = 0; i < nret-1; ++i) outputs[i] = rtas_args->rets[i+1]; - return (ulong)((nret > 0) ? rtas_args->rets[0] : 0); + ret = (ulong)((nret > 0) ? rtas_args->rets[0] : 0); + + /* Gotta do something different here, use global lock for now... */ + spin_unlock_irqrestore(&rtas.lock, s); + + if (logit) + log_error(rtas_err_buf, ERR_TYPE_RTAS_LOG, 0); + + return ret; } /* Given an RTAS status code of 990n compute the hinted delay of 10^n @@ -464,12 +483,12 @@ enter_rtas((void *)__pa((unsigned long)&get_paca()->xRtas)); args = get_paca()->xRtas; + spin_unlock_irqrestore(&rtas.lock, flags); + args.rets = (rtas_arg_t *)&(args.args[nargs]); if (args.rets[0] == -1) log_rtas_error(&args); - spin_unlock_irqrestore(&rtas.lock, flags); - /* Copy out args. */ if (copy_to_user(uargs->args + nargs, args.args + nargs, @@ -486,6 +505,8 @@ { struct rtas_args *rtas_args = &(get_paca()->xRtas); + local_irq_disable(s); + rtas_args->token = rtas_token("stop-self"); BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE); rtas_args->nargs = 0; @@ -495,6 +516,7 @@ printk("%u %u Ready to die...\n", smp_processor_id(), hard_smp_processor_id()); enter_rtas((void *)__pa(rtas_args)); + panic("Alas, I survived.\n"); } #endif /* CONFIG_HOTPLUG_CPU */ diff -Nru a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c --- a/arch/ppc64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 +++ b/arch/ppc64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 @@ -360,10 +360,8 @@ BUG_ON(! pmd_hugepage(*pmd)); page = hugepte_page(*(hugepte_t *)pmd); - if (page) { + if (page) page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT); - get_page(page); - } return page; } @@ -609,15 +607,6 @@ } } -static inline unsigned long computeHugeHptePP(unsigned int hugepte) -{ - unsigned long flags = 0x2; - - if (! (hugepte & _HUGEPAGE_RW)) - flags |= 0x1; - return flags; -} - int hash_huge_page(struct mm_struct *mm, unsigned long access, unsigned long ea, unsigned long vsid, int local) { @@ -671,7 +660,7 @@ old_pte = *ptep; new_pte = old_pte; - hpteflags = computeHugeHptePP(hugepte_val(new_pte)); + hpteflags = 0x2 | (! (hugepte_val(new_pte) & _HUGEPAGE_RW)); /* Check if pte already has an hpte (case 2) */ if (unlikely(hugepte_val(old_pte) & _HUGEPAGE_HASHPTE)) { @@ -747,7 +736,7 @@ static void flush_hash_hugepage(mm_context_t context, unsigned long ea, hugepte_t pte, int local) { - unsigned long vsid, vpn, va, hash, secondary, slot; + unsigned long vsid, vpn, va, hash, slot; BUG_ON(hugepte_bad(pte)); BUG_ON(!in_hugepage_area(context, ea)); @@ -757,8 +746,7 @@ va = (vsid << 28) | (ea & 0x0fffffff); vpn = va >> LARGE_PAGE_SHIFT; hash = hpt_hash(vpn, 1); - secondary = !!(hugepte_val(pte) & _HUGEPAGE_SECONDARY); - if (secondary) + if (hugepte_val(pte) & _HUGEPAGE_SECONDARY) hash = ~hash; slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP; slot += (hugepte_val(pte) & _HUGEPAGE_GROUP_IX) >> 5; diff -Nru a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c --- a/arch/s390/kernel/compat_signal.c Sun Apr 18 13:42:41 2004 +++ b/arch/s390/kernel/compat_signal.c Sun Apr 18 13:42:41 2004 @@ -74,8 +74,8 @@ err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { switch (from->si_code >> 16) { - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: err |= __put_user(from->si_int, &to->si_int); /* fallthrough */ case __SI_KILL >> 16: diff -Nru a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S --- a/arch/s390/kernel/compat_wrapper.S Sun Apr 18 13:42:41 2004 +++ b/arch/s390/kernel/compat_wrapper.S Sun Apr 18 13:42:41 2004 @@ -1352,3 +1352,47 @@ llgfr %r3,%r3 # compat_size_t llgtr %r4,%r4 # struct compat_statfs64 * jg compat_fstatfs64 + + .globl compat_sys_mq_open_wrapper +compat_sys_mq_open_wrapper: + llgtr %r2,%r2 # const char * + lgfr %r3,%r3 # int + llgfr %r4,%r4 # mode_t + llgtr %r5,%r5 # struct compat_mq_attr * + jg compat_sys_mq_open + + .globl sys_mq_unlink_wrapper +sys32_mq_unlink_wrapper: + llgtr %r2,%r2 # const char * + jg sys_mq_unlink + + .globl compat_sys_mq_timedsend_wrapper +compat_sys_mq_timedsend_wrapper: + lgfr %r2,%r2 # mqd_t + llgtr %r3,%r3 # const char * + llgfr %r4,%r4 # size_t + llgfr %r5,%r5 # unsigned int + llgtr %r6,%r6 # const struct compat_timespec * + jg compat_sys_mq_timedsend + + .globl compat_sys_mq_timedreceive_wrapper +compat_sys_mq_timedreceive_wrapper: + lgfr %r2,%r2 # mqd_t + llgtr %r3,%r3 # char * + llgfr %r4,%r4 # size_t + llgtr %r5,%r5 # unsigned int * + llgtr %r6,%r6 # const struct compat_timespec * + jg compat_sys_mq_timedreceive + + .globl compat_sys_mq_notify_wrapper +compat_sys_mq_notify_wrapper: + lgfr %r2,%r2 # mqd_t + llgtr %r3,%r3 # struct compat_sigevent * + jg compat_sys_mq_notify + + .globl compat_sys_mq_getsetattr_wrapper +compat_sys_mq_getsetattr_wrapper: + lgfr %r2,%r2 # mqd_t + llgtr %r3,%r3 # struct compat_mq_attr * + llgtr %r4,%r4 # struct compat_mq_attr * + jg compat_sys_mq_getsetattr diff -Nru a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S --- a/arch/s390/kernel/entry.S Sun Apr 18 13:42:40 2004 +++ b/arch/s390/kernel/entry.S Sun Apr 18 13:42:40 2004 @@ -235,7 +235,7 @@ lr %r7,%r1 # copy svc number to %r7 sla %r7,2 # *4 sysc_do_restart: - tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. bo BASED(sysc_tracesys) basr %r14,%r8 # call sys_xxxx @@ -309,6 +309,8 @@ # sysc_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 @@ -323,9 +325,11 @@ basr %r14,%r8 # call sys_xxx st %r2,SP_R2(%r15) # store return value sysc_tracenogo: - tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) bno BASED(sysc_return) l %r1,BASED(.Ltrace) + la %r2,SP_PTREGS(%r15) # load pt_regs + la %r3,1 la %r14,BASED(sysc_return) br %r1 @@ -502,7 +506,7 @@ lr %r7,%r1 # copy svc number to %r7 sla %r7,2 # *4 pgm_svcstd: - tm __TI_flags+3(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,sys_call_table-system_call(%r7,%r13) # get system call addr. bo BASED(pgm_tracesys) basr %r14,%r8 # call sys_xxxx @@ -529,6 +533,8 @@ # 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 @@ -543,9 +549,11 @@ 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 + tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) bno 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 diff -Nru a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S --- a/arch/s390/kernel/entry64.S Sun Apr 18 13:42:40 2004 +++ b/arch/s390/kernel/entry64.S Sun Apr 18 13:42:40 2004 @@ -227,7 +227,7 @@ larl %r10,sys_call_table_emu # use 31 bit emulation system calls sysc_noemu: #endif - tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) lgf %r8,0(%r7,%r10) # load address of system call routine jo sysc_tracesys basr %r14,%r8 # call sys_xxxx @@ -299,6 +299,8 @@ # special linkage: %r12 contains the return address for trace_svc # sysc_tracesys: + la %r2,SP_PTREGS(%r15) # load pt_regs + la %r3,0 srl %r7,2 stg %r7,SP_R2(%r15) brasl %r14,syscall_trace @@ -314,8 +316,10 @@ basr %r14,%r8 # call sys_xxx stg %r2,SP_R2(%r15) # store return value sysc_tracenogo: - tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) jno sysc_return + la %r2,SP_PTREGS(%r15) # load pt_regs + la %r3,1 larl %r14,sysc_return # return point is sysc_return jg syscall_trace @@ -541,7 +545,7 @@ larl %r10,sys_call_table_emu # use 31 bit emulation system calls pgm_svcper_noemu: #endif - tm __TI_flags+7(%r9),_TIF_SYSCALL_TRACE + tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) lgf %r8,0(%r7,%r10) # load address of system call routine jo pgm_tracesys basr %r14,%r8 # call sys_xxxx @@ -566,6 +570,8 @@ # 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 @@ -581,8 +587,10 @@ 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 + tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) jno 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 diff -Nru a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c --- a/arch/s390/kernel/ptrace.c Sun Apr 18 13:42:41 2004 +++ b/arch/s390/kernel/ptrace.c Sun Apr 18 13:42:41 2004 @@ -690,8 +690,16 @@ } asmlinkage void -syscall_trace(void) +syscall_trace(struct pt_regs *regs, int entryexit) { + if (unlikely(current->audit_context)) { + if (!entryexit) + audit_syscall_entry(current, regs->gprs[2], + regs->orig_gpr2, regs->gprs[3], + regs->gprs[4], regs->gprs[5]); + else + audit_syscall_exit(current, regs->gprs[2]); + } if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; if (!(current->ptrace & PT_PTRACED)) diff -Nru a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S --- a/arch/s390/kernel/syscalls.S Sun Apr 18 13:42:40 2004 +++ b/arch/s390/kernel/syscalls.S Sun Apr 18 13:42:40 2004 @@ -275,3 +275,13 @@ SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) +NI_SYSCALL /* 267 new sys_remap_file_pages */ +NI_SYSCALL /* 268 sys_mbind */ +NI_SYSCALL /* 269 sys_get_mempolicy */ +NI_SYSCALL /* 270 sys_set_mempolicy */ +SYSCALL(sys_mq_open,sys_mq_open,compat_sys_mq_open_wrapper) +SYSCALL(sys_mq_unlink,sys_mq_unlink,sys32_mq_unlink_wrapper) +SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper) +SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper) +SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) +SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper) diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c --- a/arch/sparc/kernel/process.c Sun Apr 18 13:42:40 2004 +++ b/arch/sparc/kernel/process.c Sun Apr 18 13:42:40 2004 @@ -56,6 +56,12 @@ */ void (*pm_power_off)(void); +/* + * sysctl - toggle power-off restriction for serial console + * systems in machine_power_off() + */ +int scons_pwroff = 1; + extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *); struct task_struct *last_task_used_math = NULL; @@ -187,7 +193,7 @@ void machine_power_off(void) { #ifdef CONFIG_SUN_AUXIO - if (auxio_power_register && !serial_console) + if (auxio_power_register && (!serial_console || scons_pwroff)) *auxio_power_register |= AUXIO_POWER_OFF; #endif machine_halt(); diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig --- a/arch/sparc64/Kconfig Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/Kconfig Sun Apr 18 13:42:41 2004 @@ -700,6 +700,11 @@ depends on STACK_DEBUG default y +config FRAME_POINTER + bool + depends on MCOUNT + default y + endmenu source "security/Kconfig" diff -Nru a/arch/sparc64/Makefile b/arch/sparc64/Makefile --- a/arch/sparc64/Makefile Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/Makefile Sun Apr 18 13:42:41 2004 @@ -52,7 +52,6 @@ endif ifeq ($(CONFIG_MCOUNT),y) - CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) CFLAGS := $(CFLAGS) -pg endif diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile --- a/arch/sparc64/kernel/Makefile Sun Apr 18 13:42:40 2004 +++ b/arch/sparc64/kernel/Makefile Sun Apr 18 13:42:40 2004 @@ -3,7 +3,7 @@ # EXTRA_AFLAGS := -ansi -EXTRA_CFLAGS := -Werror +# EXTRA_CFLAGS := -Werror extra-y := head.o init_task.o vmlinux.lds.s diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c --- a/arch/sparc64/kernel/ioctl32.c Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/kernel/ioctl32.c Sun Apr 18 13:42:41 2004 @@ -1106,17 +1106,6 @@ COMPATIBLE_IOCTL(WIOCSTART) COMPATIBLE_IOCTL(WIOCSTOP) COMPATIBLE_IOCTL(WIOCGSTAT) -COMPATIBLE_IOCTL(HCIUARTSETPROTO) -COMPATIBLE_IOCTL(HCIUARTGETPROTO) -COMPATIBLE_IOCTL(RFCOMMCREATEDEV) -COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) -COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) -COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) -COMPATIBLE_IOCTL(RFCOMMSTEALDLC) -COMPATIBLE_IOCTL(BNEPCONNADD) -COMPATIBLE_IOCTL(BNEPCONNDEL) -COMPATIBLE_IOCTL(BNEPGETCONNLIST) -COMPATIBLE_IOCTL(BNEPGETCONNINFO) /* And these ioctls need translation */ /* NCPFS */ HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c --- a/arch/sparc64/kernel/power.c Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/kernel/power.c Sun Apr 18 13:42:41 2004 @@ -20,6 +20,12 @@ #define __KERNEL_SYSCALLS__ #include +/* + * sysctl - toggle power-off restriction for serial console + * systems in machine_power_off() + */ +int scons_pwroff = 1; + #ifdef CONFIG_PCI static unsigned long power_reg = 0UL; @@ -44,7 +50,7 @@ void machine_power_off(void) { - if (!serial_console) { + if (!serial_console || scons_pwroff) { #ifdef CONFIG_PCI if (power_reg != 0UL) { /* Both register bits seem to have the diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c --- a/arch/sparc64/kernel/signal32.c Sun Apr 18 13:42:40 2004 +++ b/arch/sparc64/kernel/signal32.c Sun Apr 18 13:42:40 2004 @@ -129,8 +129,8 @@ err |= __put_user(from->si_trapno, &to->si_trapno); err |= __put_user((long)from->si_addr, &to->si_addr); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); diff -Nru a/arch/sparc64/lib/mcount.S b/arch/sparc64/lib/mcount.S --- a/arch/sparc64/lib/mcount.S Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/lib/mcount.S Sun Apr 18 13:42:41 2004 @@ -30,8 +30,9 @@ #endif .text .align 32 - .globl mcount + .globl mcount, _mcount mcount: +_mcount: #ifdef CONFIG_STACK_DEBUG /* * Check whether %sp is dangerously low. diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c --- a/arch/sparc64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 +++ b/arch/sparc64/mm/hugetlbpage.c Sun Apr 18 13:42:41 2004 @@ -5,6 +5,7 @@ */ #include +#include #include #include #include diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c --- a/arch/sparc64/mm/init.c Sun Apr 18 13:42:40 2004 +++ b/arch/sparc64/mm/init.c Sun Apr 18 13:42:40 2004 @@ -224,10 +224,11 @@ void flush_dcache_page(struct page *page) { + struct address_space *mapping = page_mapping(page); int dirty = test_bit(PG_dcache_dirty, &page->flags); int dirty_cpu = dcache_dirty_cpu(page); - if (page_mapping(page) && !mapping_mapped(page->mapping)) { + if (mapping && !mapping_mapped(mapping)) { if (dirty) { if (dirty_cpu == smp_processor_id()) return; diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Sun Apr 18 13:42:41 2004 +++ b/arch/x86_64/Kconfig Sun Apr 18 13:42:41 2004 @@ -338,26 +338,6 @@ depends on PCI select ACPI_BOOT -# the drivers/pci/msi.c code needs to be fixed first before enabling -config PCI_USE_VECTOR - bool "Vector-based interrupt indexing" - depends on X86_LOCAL_APIC && NOTWORKING - default n - help - This replaces the current existing IRQ-based index interrupt scheme - with the vector-base index scheme. The advantages of vector base - over IRQ base are listed below: - 1) Support MSI implementation. - 2) Support future IOxAPIC hotplug - - Note that this enables MSI, Message Signaled Interrupt, on all - MSI capable device functions detected if users also install the - MSI patch. Message Signal Interrupt enables an MSI-capable - hardware device to send an inbound Memory Write on its PCI bus - instead of asserting IRQ signal on device IRQ pin. - - If you don't know what to do here, say N. - source "drivers/pci/Kconfig" source "drivers/pcmcia/Kconfig" diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c --- a/arch/x86_64/ia32/ia32_ioctl.c Sun Apr 18 13:42:41 2004 +++ b/arch/x86_64/ia32/ia32_ioctl.c Sun Apr 18 13:42:41 2004 @@ -188,17 +188,6 @@ COMPATIBLE_IOCTL(RTC_SET_TIME) COMPATIBLE_IOCTL(RTC_WKALM_SET) COMPATIBLE_IOCTL(RTC_WKALM_RD) -COMPATIBLE_IOCTL(HCIUARTSETPROTO) -COMPATIBLE_IOCTL(HCIUARTGETPROTO) -COMPATIBLE_IOCTL(RFCOMMCREATEDEV) -COMPATIBLE_IOCTL(RFCOMMRELEASEDEV) -COMPATIBLE_IOCTL(RFCOMMGETDEVLIST) -COMPATIBLE_IOCTL(RFCOMMGETDEVINFO) -COMPATIBLE_IOCTL(RFCOMMSTEALDLC) -COMPATIBLE_IOCTL(BNEPCONNADD) -COMPATIBLE_IOCTL(BNEPCONNDEL) -COMPATIBLE_IOCTL(BNEPGETCONNLIST) -COMPATIBLE_IOCTL(BNEPGETCONNINFO) COMPATIBLE_IOCTL(FIOQSIZE) /* And these ioctls need translation */ diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c --- a/arch/x86_64/ia32/ia32_signal.c Sun Apr 18 13:42:41 2004 +++ b/arch/x86_64/ia32/ia32_signal.c Sun Apr 18 13:42:41 2004 @@ -85,8 +85,8 @@ err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: + case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ + case __SI_MESGQ >> 16: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S --- a/arch/x86_64/ia32/ia32entry.S Sun Apr 18 13:42:41 2004 +++ b/arch/x86_64/ia32/ia32entry.S Sun Apr 18 13:42:41 2004 @@ -578,6 +578,16 @@ .quad sys_tgkill .quad compat_sys_utimes .quad sys32_fadvise64_64 + .quad sys_ni_syscall /* sys_vserver */ + .quad sys_ni_syscall /* sys_mbind */ + .quad sys_ni_syscall /* 275 sys_get_mempolicy */ + .quad sys_ni_syscall /* sys_set_mempolicy */ + .quad compat_sys_mq_open + .quad sys_mq_unlink + .quad compat_sys_mq_timedsend + .quad compat_sys_mq_timedreceive /* 280 */ + .quad compat_sys_mq_notify + .quad compat_sys_mq_getsetattr /* don't forget to change IA32_NR_syscalls */ ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 diff -Nru a/crypto/Kconfig b/crypto/Kconfig --- a/crypto/Kconfig Sun Apr 18 13:42:41 2004 +++ b/crypto/Kconfig Sun Apr 18 13:42:41 2004 @@ -146,9 +146,10 @@ help ARC4 cipher algorithm. - This is a stream cipher using keys ranging from 8 bits to 2048 - bits in length. ARC4 is commonly used in protocols such as WEP - and SSL. + ARC4 is a stream cipher using keys ranging from 8 bits to 2048 + bits in length. This algorithm is required for driver-based + WEP, but it should not be for other purposes because of the + weakness of the algorithm. config CRYPTO_DEFLATE tristate "Deflate compression algorithm" diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c --- a/drivers/atm/ambassador.c Sun Apr 18 13:42:40 2004 +++ b/drivers/atm/ambassador.c Sun Apr 18 13:42:40 2004 @@ -329,7 +329,7 @@ /********** access to adapter **********/ static inline void wr_plain (const amb_dev * dev, size_t addr, u32 data) { - PRINTD (DBG_FLOW|DBG_REGS, "wr: %08x <- %08x", addr, data); + PRINTD (DBG_FLOW|DBG_REGS, "wr: %08zx <- %08x", addr, data); #ifdef AMB_MMIO dev->membase[addr / sizeof(u32)] = data; #else @@ -343,13 +343,13 @@ #else u32 data = inl (dev->iobase + addr); #endif - PRINTD (DBG_FLOW|DBG_REGS, "rd: %08x -> %08x", addr, data); + PRINTD (DBG_FLOW|DBG_REGS, "rd: %08zx -> %08x", addr, data); return data; } static inline void wr_mem (const amb_dev * dev, size_t addr, u32 data) { u32 be = cpu_to_be32 (data); - PRINTD (DBG_FLOW|DBG_REGS, "wr: %08x <- %08x b[%08x]", addr, data, be); + PRINTD (DBG_FLOW|DBG_REGS, "wr: %08zx <- %08x b[%08x]", addr, data, be); #ifdef AMB_MMIO dev->membase[addr / sizeof(u32)] = be; #else @@ -364,7 +364,7 @@ u32 be = inl (dev->iobase + addr); #endif u32 data = be32_to_cpu (be); - PRINTD (DBG_FLOW|DBG_REGS, "rd: %08x -> %08x b[%08x]", addr, data, be); + PRINTD (DBG_FLOW|DBG_REGS, "rd: %08zx -> %08x b[%08x]", addr, data, be); return data; } diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c --- a/drivers/atm/nicstar.c Sun Apr 18 13:42:40 2004 +++ b/drivers/atm/nicstar.c Sun Apr 18 13:42:40 2004 @@ -757,7 +757,7 @@ for (j = 0; j < NUM_HB; j++) { struct sk_buff *hb; - hb = alloc_skb(NS_HBUFSIZE, GFP_KERNEL); + hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); if (hb == NULL) { printk("nicstar%d: can't allocate %dth of %d huge buffers.\n", @@ -777,7 +777,7 @@ for (j = 0; j < NUM_LB; j++) { struct sk_buff *lb; - lb = alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); + lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); if (lb == NULL) { printk("nicstar%d: can't allocate %dth of %d large buffers.\n", @@ -813,7 +813,7 @@ for (j = 0; j < NUM_SB; j++) { struct sk_buff *sb; - sb = alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); + sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); if (sb == NULL) { printk("nicstar%d: can't allocate %dth of %d small buffers.\n", @@ -1315,7 +1315,7 @@ card->index); for (i = 0; i < card->sbnr.min; i++) { - sb = alloc_skb(NS_SMSKBSIZE, GFP_ATOMIC); + sb = dev_alloc_skb(NS_SMSKBSIZE); if (sb == NULL) { writel(readl(card->membase + CFG) & ~NS_CFG_EFBIE, card->membase + CFG); @@ -1341,7 +1341,7 @@ card->index); for (i = 0; i < card->lbnr.min; i++) { - lb = alloc_skb(NS_LGSKBSIZE, GFP_ATOMIC); + lb = dev_alloc_skb(NS_LGSKBSIZE); if (lb == NULL) { writel(readl(card->membase + CFG) & ~NS_CFG_EFBIE, card->membase + CFG); @@ -2178,7 +2178,7 @@ cell = skb->data; for (i = ns_rsqe_cellcount(rsqe); i; i--) { - if ((sb = alloc_skb(NS_SMSKBSIZE, GFP_ATOMIC)) == NULL) + if ((sb = dev_alloc_skb(NS_SMSKBSIZE)) == NULL) { printk("nicstar%d: Can't allocate buffers for aal0.\n", card->index); @@ -2410,7 +2410,7 @@ if (hb == NULL) /* No buffers in the queue */ { - hb = alloc_skb(NS_HBUFSIZE, GFP_ATOMIC); + hb = dev_alloc_skb(NS_HBUFSIZE); if (hb == NULL) { printk("nicstar%d: Out of huge buffers.\n", card->index); @@ -2424,7 +2424,7 @@ else if (card->hbpool.count < card->hbnr.min) { struct sk_buff *new_hb; - if ((new_hb = alloc_skb(NS_HBUFSIZE, GFP_ATOMIC)) != NULL) + if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) { skb_queue_tail(&card->hbpool.queue, new_hb); card->hbpool.count++; @@ -2435,14 +2435,14 @@ if (--card->hbpool.count < card->hbnr.min) { struct sk_buff *new_hb; - if ((new_hb = alloc_skb(NS_HBUFSIZE, GFP_ATOMIC)) != NULL) + if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) { skb_queue_tail(&card->hbpool.queue, new_hb); card->hbpool.count++; } if (card->hbpool.count < card->hbnr.min) { - if ((new_hb = alloc_skb(NS_HBUFSIZE, GFP_ATOMIC)) != NULL) + if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL) { skb_queue_tail(&card->hbpool.queue, new_hb); card->hbpool.count++; @@ -2524,7 +2524,7 @@ do { - sb = alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); + sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); if (sb == NULL) break; skb_queue_tail(&card->sbpool.queue, sb); @@ -2547,7 +2547,7 @@ do { - lb = alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); + lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); if (lb == NULL) break; skb_queue_tail(&card->lbpool.queue, lb); @@ -2566,7 +2566,7 @@ while (card->hbpool.count < card->hbnr.init) { - hb = alloc_skb(NS_HBUFSIZE, GFP_KERNEL); + hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); if (hb == NULL) break; skb_queue_tail(&card->hbpool.queue, hb); @@ -2638,7 +2638,7 @@ if (card->sbfqc < card->sbnr.init) { struct sk_buff *new_sb; - if ((new_sb = alloc_skb(NS_SMSKBSIZE, GFP_ATOMIC)) != NULL) + if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { skb_queue_tail(&card->sbpool.queue, new_sb); skb_reserve(new_sb, NS_AAL0_HEADER); @@ -2650,7 +2650,7 @@ #endif /* NS_USE_DESTRUCTORS */ { struct sk_buff *new_sb; - if ((new_sb = alloc_skb(NS_SMSKBSIZE, GFP_ATOMIC)) != NULL) + if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) { skb_queue_tail(&card->sbpool.queue, new_sb); skb_reserve(new_sb, NS_AAL0_HEADER); @@ -2671,7 +2671,7 @@ if (card->lbfqc < card->lbnr.init) { struct sk_buff *new_lb; - if ((new_lb = alloc_skb(NS_LGSKBSIZE, GFP_ATOMIC)) != NULL) + if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { skb_queue_tail(&card->lbpool.queue, new_lb); skb_reserve(new_lb, NS_SMBUFSIZE); @@ -2683,7 +2683,7 @@ #endif /* NS_USE_DESTRUCTORS */ { struct sk_buff *new_lb; - if ((new_lb = alloc_skb(NS_LGSKBSIZE, GFP_ATOMIC)) != NULL) + if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) { skb_queue_tail(&card->lbpool.queue, new_lb); skb_reserve(new_lb, NS_SMBUFSIZE); @@ -2877,7 +2877,7 @@ { struct sk_buff *sb; - sb = alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); + sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL); if (sb == NULL) return -ENOMEM; skb_queue_tail(&card->sbpool.queue, sb); @@ -2891,7 +2891,7 @@ { struct sk_buff *lb; - lb = alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); + lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL); if (lb == NULL) return -ENOMEM; skb_queue_tail(&card->lbpool.queue, lb); @@ -2920,7 +2920,7 @@ { struct sk_buff *hb; - hb = alloc_skb(NS_HBUFSIZE, GFP_KERNEL); + hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL); if (hb == NULL) return -ENOMEM; ns_grab_int_lock(card, flags); diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig --- a/drivers/base/Kconfig Sun Apr 18 13:42:40 2004 +++ b/drivers/base/Kconfig Sun Apr 18 13:42:40 2004 @@ -9,14 +9,14 @@ the kernel tree does. config DEBUG_DRIVER - bool "Driver Core verbose debug messages" - depends on DEBUG_KERNEL - help - Say Y here if you want the Driver core to produce a bunch of - debug messages to the system log. Select this if you are having a - problem with the driver core and want to see more of what is - going on. + bool "Driver Core verbose debug messages" + depends on DEBUG_KERNEL + help + Say Y here if you want the Driver core to produce a bunch of + debug messages to the system log. Select this if you are having a + problem with the driver core and want to see more of what is + going on. - If you are unsure about this, say N here. + If you are unsure about this, say N here. endmenu diff -Nru a/drivers/base/class.c b/drivers/base/class.c --- a/drivers/base/class.c Sun Apr 18 13:42:41 2004 +++ b/drivers/base/class.c Sun Apr 18 13:42:41 2004 @@ -155,8 +155,7 @@ static void class_device_dev_unlink(struct class_device * class_dev) { - if (class_dev->dev) - sysfs_remove_link(&class_dev->kobj, "device"); + sysfs_remove_link(&class_dev->kobj, "device"); } static int class_device_driver_link(struct class_device * class_dev) @@ -169,8 +168,7 @@ static void class_device_driver_unlink(struct class_device * class_dev) { - if ((class_dev->dev) && (class_dev->dev->driver)) - sysfs_remove_link(&class_dev->kobj, "driver"); + sysfs_remove_link(&class_dev->kobj, "driver"); } diff -Nru a/drivers/block/floppy98.c b/drivers/block/floppy98.c --- a/drivers/block/floppy98.c Sun Apr 18 13:42:40 2004 +++ b/drivers/block/floppy98.c Sun Apr 18 13:42:40 2004 @@ -168,8 +168,11 @@ #include #include #include -#define FDPATCHES #include +#include +#include +#include /* for the compatibility eject ioctl */ +#include /* * 1998/1/21 -- Richard Gooch -- devfs support @@ -179,7 +182,6 @@ #include #define FLOPPY98_MOTOR_MASK 0x08 -#define FDPATCHES #include #define FD98_STATUS (0 + FD_IOPORT ) #define FD98_DATA (2 + FD_IOPORT ) @@ -250,9 +252,10 @@ */ static spinlock_t floppy_lock = SPIN_LOCK_UNLOCKED; +static struct completion device_release; static unsigned short virtual_dma_port=0x3f0; -void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs); +irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs); static int set_mode(char mask, char data); static void register_devfs_entries (int drive) __init; @@ -987,9 +990,9 @@ static DECLARE_WORK(floppy_work, NULL, NULL); -static void schedule_bh( void (*handler)(void*) ) +static void schedule_bh(void (*handler) (void)) { - PREPARE_WORK(&floppy_work, handler, NULL); + PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL); schedule_work(&floppy_work); } @@ -1627,7 +1630,7 @@ } /* interrupt handler. Note that this can be called externally on the Sparc */ -void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs) +irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs) { void (*handler)(void) = do_floppy; int do_print; @@ -1648,7 +1651,7 @@ printk("floppy interrupt on bizarre fdc %d\n",fdc); printk("handler=%p\n", handler); is_alive("bizarre fdc"); - return; + return IRQ_NONE; } FDCS->reset = 0; @@ -1661,7 +1664,7 @@ * activity. */ - do_print = !handler && !initialising; + do_print = !handler && print_unex && !initialising; inr = result(); if (inr && do_print) @@ -1701,13 +1704,16 @@ } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2); } if (handler) { - schedule_bh( (void *)(void *) handler); + schedule_bh(handler); } else { #if 0 FDCS->reset = 1; #endif } is_alive("normal interrupt end"); + + /* FIXME! Was it really for us? */ + return IRQ_HANDLED; } static void recalibrate_floppy(void) @@ -4231,11 +4237,16 @@ static int have_no_fdc= -ENODEV; +static void floppy_device_release(struct device *dev) +{ + complete(&device_release); +} + static struct platform_device floppy_device = { .name = "floppy", .id = 0, .dev = { - .name = "Floppy Drive", + .release = floppy_device_release, }, }; @@ -4267,10 +4278,8 @@ } devfs_mk_dir (NULL, "floppy", NULL); - if (register_blkdev(FLOPPY_MAJOR,"fd")) { - err = -EBUSY; + if ((err = register_blkdev(FLOPPY_MAJOR,"fd"))) goto out; - } for (i=0; imajor = FLOPPY_MAJOR; @@ -4288,7 +4297,7 @@ else floppy_sizes[i] = MAX_DISK_SIZE << 1; - floppy_queue = blk_init_queue(do_fd_request, &floppy_lock) + floppy_queue = blk_init_queue(do_fd_request, &floppy_lock); if (!floppy_queue) goto out_queue; @@ -4628,10 +4637,14 @@ { int drive; + init_completion(&device_release); platform_device_unregister(&floppy_device); blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); unregister_blkdev(FLOPPY_MAJOR, "fd"); + for (drive = 0; drive < N_DRIVE; drive++) { + del_timer_sync(&motor_off_timer[drive]); + if ((allowed_drive_mask & (1 << drive)) && fdc_state[FDC(drive)].version != FDC_NONE) { del_gendisk(disks[drive]); @@ -4641,9 +4654,17 @@ } devfs_remove("floppy"); + del_timer_sync(&fd_timeout); + del_timer_sync(&fd_timer); blk_cleanup_queue(floppy_queue); + + if (usage_count) + floppy_release_irq_and_dma(); + /* eject disk, if any */ fd_eject(0); + + wait_for_completion(&device_release); } MODULE_PARM(floppy,"s"); diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c --- a/drivers/block/ll_rw_blk.c Sun Apr 18 13:42:40 2004 +++ b/drivers/block/ll_rw_blk.c Sun Apr 18 13:42:40 2004 @@ -2429,7 +2429,7 @@ * interfaces, @bio must be presetup and ready for I/O. * */ -int submit_bio(int rw, struct bio *bio) +void submit_bio(int rw, struct bio *bio) { int count = bio_sectors(bio); @@ -2451,7 +2451,6 @@ } generic_make_request(bio); - return 1; } EXPORT_SYMBOL(submit_bio); @@ -2733,7 +2732,7 @@ struct gendisk *disk = req->rq_disk; struct completion *waiting = req->waiting; - if (unlikely(laptop_mode)) + if (unlikely(laptop_mode) && blk_fs_request(req)) laptop_io_completion(); if (disk && blk_fs_request(req)) { diff -Nru a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig --- a/drivers/bluetooth/Kconfig Sun Apr 18 13:42:40 2004 +++ b/drivers/bluetooth/Kconfig Sun Apr 18 13:42:40 2004 @@ -104,15 +104,13 @@ config BT_HCIBT3C tristate "HCI BT3C (PC Card) driver" depends on PCMCIA + select FW_LOADER help Bluetooth HCI BT3C (PC Card) driver. This driver provides support for Bluetooth PCMCIA devices with 3Com BT3C interface: 3Com Bluetooth Card (3CRWB6096) HP Bluetooth Card - - The HCI BT3C driver uses external firmware loader program provided in - the BlueFW package. For more information, see . Say Y here to compile support for HCI BT3C devices into the kernel or say M to compile it as module (bt3c_cs). diff -Nru a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c --- a/drivers/bluetooth/bcm203x.c Sun Apr 18 13:42:40 2004 +++ b/drivers/bluetooth/bcm203x.c Sun Apr 18 13:42:40 2004 @@ -74,7 +74,7 @@ struct timer_list timer; struct urb *urb; - unsigned char buffer[4096]; + unsigned char *buffer; unsigned char *fw_data; unsigned int fw_size; @@ -99,8 +99,7 @@ case BCM203X_LOAD_MINIDRV: memcpy(data->buffer, "#", 1); - usb_fill_bulk_urb(urb, udev, - usb_sndbulkpipe(udev, BCM203X_OUT_EP), + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, 1, bcm203x_complete, data); data->state = BCM203X_SELECT_MEMORY; @@ -109,8 +108,7 @@ break; case BCM203X_SELECT_MEMORY: - usb_fill_int_urb(urb, udev, - usb_rcvintpipe(udev, BCM203X_IN_EP), + usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_MEMORY; @@ -130,20 +128,15 @@ case BCM203X_LOAD_FIRMWARE: if (data->fw_sent == data->fw_size) { - usb_fill_int_urb(urb, udev, - usb_rcvintpipe(udev, BCM203X_IN_EP), - data->buffer, 32, - bcm203x_complete, data, 1); + usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP), + data->buffer, 32, bcm203x_complete, data, 1); data->state = BCM203X_CHECK_FIRMWARE; } else { - len = min_t(uint, data->fw_size - data->fw_sent, - sizeof(data->buffer)); + len = min_t(uint, data->fw_size - data->fw_sent, 4096); - usb_fill_bulk_urb(urb, udev, - usb_sndbulkpipe(udev, BCM203X_OUT_EP), - data->fw_data + data->fw_sent, len, - bcm203x_complete, data); + usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), + data->fw_data + data->fw_sent, len, bcm203x_complete, data); data->fw_sent += len; } @@ -177,6 +170,7 @@ const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); struct bcm203x_data *data; + int size; BT_DBG("intf %p id %p", intf, id); @@ -210,18 +204,20 @@ BT_DBG("minidrv data %p size %d", firmware->data, firmware->size); - if (firmware->size > sizeof(data->buffer)) { - BT_ERR("Mini driver exceeds size of buffer"); + size = max_t(uint, firmware->size, 4096); + + data->buffer = kmalloc(size, GFP_KERNEL); + if (!data->buffer) { + BT_ERR("Can't allocate memory for mini driver"); release_firmware(firmware); usb_free_urb(data->urb); kfree(data); - return -EIO; + return -ENOMEM; } memcpy(data->buffer, firmware->data, firmware->size); - usb_fill_bulk_urb(data->urb, udev, - usb_sndbulkpipe(udev, BCM203X_OUT_EP), + usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP), data->buffer, firmware->size, bcm203x_complete, data); release_firmware(firmware); @@ -229,6 +225,7 @@ if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { BT_ERR("Firmware request failed"); usb_free_urb(data->urb); + kfree(data->buffer); kfree(data); return -EIO; } @@ -239,6 +236,7 @@ if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); usb_free_urb(data->urb); + kfree(data->buffer); kfree(data); return -ENOMEM; } @@ -272,6 +270,7 @@ usb_free_urb(data->urb); kfree(data->fw_data); + kfree(data->buffer); kfree(data); } diff -Nru a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c --- a/drivers/bluetooth/bfusb.c Sun Apr 18 13:42:41 2004 +++ b/drivers/bluetooth/bfusb.c Sun Apr 18 13:42:41 2004 @@ -98,6 +98,14 @@ static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs); static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs); +static inline void bfusb_wait_for_urb(struct urb *urb) +{ + while (atomic_read(&urb->count) > 1) { + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout((5 * HZ + 999) / 1000); + } +} + static struct urb *bfusb_get_completed(struct bfusb *bfusb) { struct sk_buff *skb; @@ -114,7 +122,7 @@ return urb; } -static inline void bfusb_unlink_urbs(struct bfusb *bfusb) +static void bfusb_unlink_urbs(struct bfusb *bfusb) { struct sk_buff *skb; struct urb *urb; @@ -124,6 +132,7 @@ while ((skb = skb_dequeue(&bfusb->pending_q))) { urb = ((struct bfusb_scb *) skb->cb)->urb; usb_unlink_urb(urb); + bfusb_wait_for_urb(urb); skb_queue_tail(&bfusb->completed_q, skb); } @@ -359,11 +368,11 @@ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); - if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) - return; - read_lock(&bfusb->lock); + if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) + goto unlock; + if (urb->status || !count) goto resubmit; @@ -414,6 +423,7 @@ bfusb->hdev->name, urb, err); } +unlock: read_unlock(&bfusb->lock); } diff -Nru a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c --- a/drivers/bluetooth/bluecard_cs.c Sun Apr 18 13:42:41 2004 +++ b/drivers/bluetooth/bluecard_cs.c Sun Apr 18 13:42:41 2004 @@ -174,6 +174,9 @@ bluecard_info_t *info = (bluecard_info_t *)arg; unsigned int iobase = info->link.io.BasePort1; + if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) + return; + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) { /* Disable activity LED */ outb(0x08 | 0x20, iobase + 0x30); @@ -188,6 +191,9 @@ { unsigned int iobase = info->link.io.BasePort1; + if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) + return; + if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) { /* Enable activity LED */ outb(0x10 | 0x40, iobase + 0x30); @@ -505,13 +511,13 @@ unsigned int iobase; unsigned char reg; - if (!info) { + if (!info || !info->hdev) { BT_ERR("Call of irq %d for unknown device", irq); return IRQ_NONE; } if (!test_bit(CARD_READY, &(info->hw_state))) - return IRQ_NONE; + return IRQ_HANDLED; iobase = info->link.io.BasePort1; @@ -629,13 +635,16 @@ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data); unsigned int iobase = info->link.io.BasePort1; - bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); + if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) + bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); if (test_and_set_bit(HCI_RUNNING, &(hdev->flags))) return 0; - /* Enable LED */ - outb(0x08 | 0x20, iobase + 0x30); + if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { + /* Enable LED */ + outb(0x08 | 0x20, iobase + 0x30); + } return 0; } @@ -651,8 +660,10 @@ bluecard_hci_flush(hdev); - /* Disable LED */ - outb(0x00, iobase + 0x30); + if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { + /* Disable LED */ + outb(0x00, iobase + 0x30); + } return 0; } @@ -725,6 +736,27 @@ info->rx_count = 0; info->rx_skb = NULL; + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) { + BT_ERR("Can't allocate HCI device"); + return -ENOMEM; + } + + info->hdev = hdev; + + hdev->type = HCI_PCCARD; + hdev->driver_data = info; + + hdev->open = bluecard_hci_open; + hdev->close = bluecard_hci_close; + hdev->flush = bluecard_hci_flush; + hdev->send = bluecard_hci_send_frame; + hdev->destruct = bluecard_hci_destruct; + hdev->ioctl = bluecard_hci_ioctl; + + hdev->owner = THIS_MODULE; + id = inb(iobase + 0x30); if ((id & 0x0f) == 0x02) @@ -759,6 +791,24 @@ info->ctrl_reg |= REG_CONTROL_INTERRUPT; outb(info->ctrl_reg, iobase + REG_CONTROL); + if ((id & 0x0f) == 0x03) { + /* Disable RTS */ + info->ctrl_reg |= REG_CONTROL_RTS; + outb(info->ctrl_reg, iobase + REG_CONTROL); + + /* Set baud rate */ + info->ctrl_reg |= 0x03; + outb(info->ctrl_reg, iobase + REG_CONTROL); + + /* Enable RTS */ + info->ctrl_reg &= ~REG_CONTROL_RTS; + outb(info->ctrl_reg, iobase + REG_CONTROL); + + set_bit(XMIT_BUF_ONE_READY, &(info->tx_state)); + set_bit(XMIT_BUF_TWO_READY, &(info->tx_state)); + set_bit(XMIT_SENDING_READY, &(info->tx_state)); + } + /* Start the RX buffers */ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND); outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND); @@ -776,30 +826,10 @@ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((HZ * 5) / 4); // or set it to 3/2 - - /* Initialize and register HCI device */ - hdev = hci_alloc_dev(); - if (!hdev) { - BT_ERR("Can't allocate HCI device"); - return -ENOMEM; - } - - info->hdev = hdev; - - hdev->type = HCI_PCCARD; - hdev->driver_data = info; - - hdev->open = bluecard_hci_open; - hdev->close = bluecard_hci_close; - hdev->flush = bluecard_hci_flush; - hdev->send = bluecard_hci_send_frame; - hdev->destruct = bluecard_hci_destruct; - hdev->ioctl = bluecard_hci_ioctl; - - hdev->owner = THIS_MODULE; - + /* Register HCI device */ if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); + info->hdev = NULL; hci_free_dev(hdev); return -ENODEV; } @@ -813,6 +843,9 @@ unsigned int iobase = info->link.io.BasePort1; struct hci_dev *hdev = info->hdev; + if (!hdev) + return -ENODEV; + bluecard_hci_close(hdev); clear_bit(CARD_READY, &(info->hw_state)); @@ -1016,6 +1049,8 @@ if (link->state & DEV_PRESENT) bluecard_close(info); + + del_timer(&(info->timer)); link->dev = NULL; diff -Nru a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c --- a/drivers/bluetooth/bt3c_cs.c Sun Apr 18 13:42:41 2004 +++ b/drivers/bluetooth/bt3c_cs.c Sun Apr 18 13:42:41 2004 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ #include #include +#include +#include + #include #include #include @@ -361,7 +365,7 @@ unsigned int iobase; int iir; - if (!info) { + if (!info || !info->hdev) { BT_ERR("Call of irq %d for unknown device", irq); return IRQ_NONE; } @@ -379,7 +383,8 @@ } else if ((stat & 0xff) != 0xff) { if (stat & 0x0020) { int stat = bt3c_read(iobase, 0x7002) & 0x10; - BT_ERR("Antenna %s", stat ? "out" : "in"); + BT_INFO("%s: Antenna %s", info->hdev->name, + stat ? "out" : "in"); } if (stat & 0x0001) bt3c_receive(info); @@ -481,36 +486,101 @@ -/* ======================== User mode firmware loader ======================== */ +/* ======================== Card services HCI interaction ======================== */ -#define FW_LOADER "/sbin/bluefw" +static struct device bt3c_device = { + .bus_id = "pcmcia", +}; -static int bt3c_firmware_load(bt3c_info_t *info) +static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count) { - char dev[16]; - int err; + char *ptr = (char *) firmware; + char b[9]; + unsigned int iobase, size, addr, fcs, tmp; + int i, err = 0; + + iobase = info->link.io.BasePort1; - char *argv[] = { FW_LOADER, "pccard", dev, NULL }; - char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + /* Reset */ + bt3c_io_write(iobase, 0x8040, 0x0404); + bt3c_io_write(iobase, 0x8040, 0x0400); + + udelay(1); + + bt3c_io_write(iobase, 0x8040, 0x0404); + + udelay(17); + + /* Load */ + while (count) { + if (ptr[0] != 'S') { + BT_ERR("Bad address in firmware"); + err = -EFAULT; + goto error; + } + + memset(b, 0, sizeof(b)); + memcpy(b, ptr + 2, 2); + size = simple_strtol(b, NULL, 16); + + memset(b, 0, sizeof(b)); + memcpy(b, ptr + 4, 8); + addr = simple_strtol(b, NULL, 16); + + memset(b, 0, sizeof(b)); + memcpy(b, ptr + (size * 2) + 2, 2); + fcs = simple_strtol(b, NULL, 16); + + memset(b, 0, sizeof(b)); + for (tmp = 0, i = 0; i < size; i++) { + memcpy(b, ptr + (i * 2) + 2, 2); + tmp += simple_strtol(b, NULL, 16); + } - sprintf(dev, "%04x", info->link.io.BasePort1); + if (((tmp + fcs) & 0xff) != 0xff) { + BT_ERR("Checksum error in firmware"); + err = -EILSEQ; + goto error; + } - err = call_usermodehelper(FW_LOADER, argv, envp, 1); - if (err) - BT_ERR("Failed to run \"%s pccard %s\" (errno=%d)", FW_LOADER, dev, err); + if (ptr[1] == '3') { + bt3c_address(iobase, addr); - return err; -} + memset(b, 0, sizeof(b)); + for (i = 0; i < (size - 4) / 2; i++) { + memcpy(b, ptr + (i * 4) + 12, 4); + tmp = simple_strtol(b, NULL, 16); + bt3c_put(iobase, tmp); + } + } + + ptr += (size * 2) + 6; + count -= (size * 2) + 6; + } + udelay(17); + /* Boot */ + bt3c_address(iobase, 0x3000); + outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL); -/* ======================== Card services HCI interaction ======================== */ +error: + udelay(17); + + /* Clear */ + bt3c_io_write(iobase, 0x7006, 0x0000); + bt3c_io_write(iobase, 0x7005, 0x0000); + bt3c_io_write(iobase, 0x7001, 0x0000); + + return err; +} int bt3c_open(bt3c_info_t *info) { + const struct firmware *firmware; struct hci_dev *hdev; int err; @@ -522,18 +592,7 @@ info->rx_count = 0; info->rx_skb = NULL; - /* Load firmware */ - - if ((err = bt3c_firmware_load(info)) < 0) - return err; - - /* Timeout before it is safe to send the first HCI packet */ - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ); - - - /* Initialize and register HCI device */ + /* Initialize HCI device */ hdev = hci_alloc_dev(); if (!hdev) { BT_ERR("Can't allocate HCI device"); @@ -545,28 +604,57 @@ hdev->type = HCI_PCCARD; hdev->driver_data = info; - hdev->open = bt3c_hci_open; - hdev->close = bt3c_hci_close; - hdev->flush = bt3c_hci_flush; - hdev->send = bt3c_hci_send_frame; + hdev->open = bt3c_hci_open; + hdev->close = bt3c_hci_close; + hdev->flush = bt3c_hci_flush; + hdev->send = bt3c_hci_send_frame; hdev->destruct = bt3c_hci_destruct; - hdev->ioctl = bt3c_hci_ioctl; + hdev->ioctl = bt3c_hci_ioctl; hdev->owner = THIS_MODULE; - - if (hci_register_dev(hdev) < 0) { + + /* Load firmware */ + err = request_firmware(&firmware, "BT3CPCC.bin", &bt3c_device); + if (err < 0) { + BT_ERR("Firmware request failed"); + goto error; + } + + err = bt3c_load_firmware(info, firmware->data, firmware->size); + + release_firmware(firmware); + + if (err < 0) { + BT_ERR("Firmware loading failed"); + goto error; + } + + /* Timeout before it is safe to send the first HCI packet */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + + /* Register HCI device */ + err = hci_register_dev(hdev); + if (err < 0) { BT_ERR("Can't register HCI device"); - hci_free_dev(hdev); - return -ENODEV; + goto error; } return 0; + +error: + info->hdev = NULL; + hci_free_dev(hdev); + return err; } int bt3c_close(bt3c_info_t *info) { struct hci_dev *hdev = info->hdev; + + if (!hdev) + return -ENODEV; bt3c_hci_close(hdev); diff -Nru a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c --- a/drivers/bluetooth/btuart_cs.c Sun Apr 18 13:42:41 2004 +++ b/drivers/bluetooth/btuart_cs.c Sun Apr 18 13:42:41 2004 @@ -308,7 +308,7 @@ int boguscount = 0; int iir, lsr; - if (!info) { + if (!info || !info->hdev) { BT_ERR("Call of irq %d for unknown device", irq); return IRQ_NONE; } @@ -504,6 +504,27 @@ info->rx_count = 0; info->rx_skb = NULL; + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) { + BT_ERR("Can't allocate HCI device"); + return -ENOMEM; + } + + info->hdev = hdev; + + hdev->type = HCI_PCCARD; + hdev->driver_data = info; + + hdev->open = btuart_hci_open; + hdev->close = btuart_hci_close; + hdev->flush = btuart_hci_flush; + hdev->send = btuart_hci_send_frame; + hdev->destruct = btuart_hci_destruct; + hdev->ioctl = btuart_hci_ioctl; + + hdev->owner = THIS_MODULE; + spin_lock_irqsave(&(info->lock), flags); /* Reset UART */ @@ -527,30 +548,10 @@ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); - - /* Initialize and register HCI device */ - hdev = hci_alloc_dev(); - if (!hdev) { - BT_ERR("Can't allocate HCI device"); - return -ENOMEM; - } - - info->hdev = hdev; - - hdev->type = HCI_PCCARD; - hdev->driver_data = info; - - hdev->open = btuart_hci_open; - hdev->close = btuart_hci_close; - hdev->flush = btuart_hci_flush; - hdev->send = btuart_hci_send_frame; - hdev->destruct = btuart_hci_destruct; - hdev->ioctl = btuart_hci_ioctl; - - hdev->owner = THIS_MODULE; - + /* Register HCI device */ if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); + info->hdev = NULL; hci_free_dev(hdev); return -ENODEV; } @@ -564,6 +565,9 @@ unsigned long flags; unsigned int iobase = info->link.io.BasePort1; struct hci_dev *hdev = info->hdev; + + if (!hdev) + return -ENODEV; btuart_hci_close(hdev); diff -Nru a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c --- a/drivers/bluetooth/dtl1_cs.c Sun Apr 18 13:42:40 2004 +++ b/drivers/bluetooth/dtl1_cs.c Sun Apr 18 13:42:40 2004 @@ -312,7 +312,7 @@ int boguscount = 0; int iir, lsr; - if (!info) { + if (!info || !info->hdev) { BT_ERR("Call of irq %d for unknown device", irq); return IRQ_NONE; } @@ -483,6 +483,27 @@ set_bit(XMIT_WAITING, &(info->tx_state)); + /* Initialize HCI device */ + hdev = hci_alloc_dev(); + if (!hdev) { + BT_ERR("Can't allocate HCI device"); + return -ENOMEM; + } + + info->hdev = hdev; + + hdev->type = HCI_PCCARD; + hdev->driver_data = info; + + hdev->open = dtl1_hci_open; + hdev->close = dtl1_hci_close; + hdev->flush = dtl1_hci_flush; + hdev->send = dtl1_hci_send_frame; + hdev->destruct = dtl1_hci_destruct; + hdev->ioctl = dtl1_hci_ioctl; + + hdev->owner = THIS_MODULE; + spin_lock_irqsave(&(info->lock), flags); /* Reset UART */ @@ -506,30 +527,10 @@ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ * 2); - - /* Initialize and register HCI device */ - hdev = hci_alloc_dev(); - if (!hdev) { - BT_ERR("Can't allocate HCI device"); - return -ENOMEM; - } - - info->hdev = hdev; - - hdev->type = HCI_PCCARD; - hdev->driver_data = info; - - hdev->open = dtl1_hci_open; - hdev->close = dtl1_hci_close; - hdev->flush = dtl1_hci_flush; - hdev->send = dtl1_hci_send_frame; - hdev->destruct = dtl1_hci_destruct; - hdev->ioctl = dtl1_hci_ioctl; - - hdev->owner = THIS_MODULE; - + /* Register HCI device */ if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); + info->hdev = NULL; hci_free_dev(hdev); return -ENODEV; } @@ -543,6 +544,9 @@ unsigned long flags; unsigned int iobase = info->link.io.BasePort1; struct hci_dev *hdev = info->hdev; + + if (!hdev) + return -ENODEV; dtl1_hci_close(hdev); diff -Nru a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h --- a/drivers/bluetooth/hci_uart.h Sun Apr 18 13:42:40 2004 +++ b/drivers/bluetooth/hci_uart.h Sun Apr 18 13:42:40 2004 @@ -35,11 +35,12 @@ #define HCIUARTGETPROTO _IOR('U', 201, int) /* UART protocols */ -#define HCI_UART_MAX_PROTO 3 +#define HCI_UART_MAX_PROTO 4 #define HCI_UART_H4 0 #define HCI_UART_BCSP 1 -#define HCI_UART_NCSP 2 +#define HCI_UART_3WIRE 2 +#define HCI_UART_H4DS 3 #ifdef __KERNEL__ struct hci_uart; diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c --- a/drivers/bluetooth/hci_usb.c Sun Apr 18 13:42:41 2004 +++ b/drivers/bluetooth/hci_usb.c Sun Apr 18 13:42:41 2004 @@ -109,8 +109,7 @@ sizeof(struct usb_iso_packet_descriptor) * isoc, gfp); if (_urb) { memset(_urb, 0, sizeof(*_urb)); - _urb->urb.count = (atomic_t)ATOMIC_INIT(1); - spin_lock_init(&_urb->urb.lock); + usb_init_urb(&_urb->urb); } return _urb; } @@ -341,6 +340,14 @@ return 0; } +static inline void hci_usb_wait_for_urb(struct urb *urb) +{ + while (atomic_read(&urb->count) > 1) { + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout((5 * HZ + 999) / 1000); + } +} + static void hci_usb_unlink_urbs(struct hci_usb *husb) { int i; @@ -357,6 +364,7 @@ BT_DBG("%s unlinking _urb %p type %d urb %p", husb->hdev->name, _urb, _urb->type, urb); usb_unlink_urb(urb); + hci_usb_wait_for_urb(urb); _urb_queue_tail(__completed_q(husb, _urb->type), _urb); } @@ -699,11 +707,11 @@ BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb, _urb->type, urb->status, count, urb->transfer_flags); - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - read_lock(&husb->completion_lock); + if (!test_bit(HCI_RUNNING, &hdev->flags)) + goto unlock; + if (urb->status || !count) goto resubmit; @@ -739,6 +747,7 @@ BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb, _urb->type, err); +unlock: read_unlock(&husb->completion_lock); } diff -Nru a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c --- a/drivers/char/dsp56k.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/dsp56k.c Sun Apr 18 13:42:41 2004 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -149,6 +150,8 @@ int tx_wsize, rx_wsize; } dsp56k; +static struct class_simple *dsp56k_class; + static int dsp56k_reset(void) { u_char status; @@ -502,6 +505,8 @@ static int __init dsp56k_init_driver(void) { + int err = 0; + if(!MACH_IS_ATARI || !ATARIHW_PRESENT(DSP56K)) { printk("DSP56k driver: Hardware not present\n"); return -ENODEV; @@ -511,17 +516,35 @@ printk("DSP56k driver: Unable to register driver\n"); return -ENODEV; } + dsp56k_class = class_simple_create(THIS_MODULE, "dsp56k"); + if (IS_ERR(dsp56k_class)) { + err = PTR_ERR(dsp56k_class); + goto out_chrdev; + } + class_simple_device_add(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); - devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0), + err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k"); + if(err) + goto out_class; printk(banner); - return 0; + goto out; + +out_class: + class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0)); + class_simple_destroy(dsp56k_class); +out_chrdev: + unregister_chrdev(DSP56K_MAJOR, "dsp56k"); +out: + return err; } module_init(dsp56k_init_driver); static void __exit dsp56k_cleanup_driver(void) { + class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0)); + class_simple_destroy(dsp56k_class); unregister_chrdev(DSP56K_MAJOR, "dsp56k"); devfs_remove("dsp56k"); } diff -Nru a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c --- a/drivers/char/ftape/zftape/zftape-init.c Sun Apr 18 13:42:40 2004 +++ b/drivers/char/ftape/zftape/zftape-init.c Sun Apr 18 13:42:40 2004 @@ -38,6 +38,7 @@ #include #include +#include #include "../zftape/zftape-init.h" #include "../zftape/zftape-read.h" @@ -103,6 +104,8 @@ .release = zft_close, }; +static struct class_simple *zft_class; + /* Open floppy tape device */ static int zft_open(struct inode *ino, struct file *filep) @@ -341,22 +344,29 @@ "installing zftape VFS interface for ftape driver ..."); TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),); + zft_class = class_simple_create(THIS_MODULE, "zft"); for (i = 0; i < 4; i++) { + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "qft%i", i); + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4), S_IFCHR | S_IRUSR | S_IWUSR, "nqft%i", i); + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16), S_IFCHR | S_IRUSR | S_IWUSR, "zqft%i", i); + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20), S_IFCHR | S_IRUSR | S_IWUSR, "nzqft%i", i); + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32), S_IFCHR | S_IRUSR | S_IWUSR, "rawqft%i", i); + class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36), S_IFCHR | S_IRUSR | S_IWUSR, "nrawqft%i", i); @@ -386,12 +396,19 @@ } for (i = 0; i < 4; i++) { devfs_remove("qft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i)); devfs_remove("nqft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 4)); devfs_remove("zqft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 16)); devfs_remove("nzqft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 20)); devfs_remove("rawqft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 32)); devfs_remove("nrawqft%i", i); + class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 36)); } + class_simple_destroy(zft_class); zft_uninit_mem(); /* release remaining memory, if any */ printk(KERN_INFO "zftape successfully unloaded.\n"); TRACE_EXIT; diff -Nru a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c --- a/drivers/char/ipmi/ipmi_si_intf.c Sun Apr 18 13:42:40 2004 +++ b/drivers/char/ipmi/ipmi_si_intf.c Sun Apr 18 13:42:40 2004 @@ -51,6 +51,7 @@ #include #include #include +#include #ifdef CONFIG_HIGH_RES_TIMERS #include # if defined(schedule_next_int) diff -Nru a/drivers/char/istallion.c b/drivers/char/istallion.c --- a/drivers/char/istallion.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/istallion.c Sun Apr 18 13:42:41 2004 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -795,6 +796,8 @@ /*****************************************************************************/ +static struct class_simple *istallion_class; + #ifdef MODULE /* @@ -853,9 +856,12 @@ return; } put_tty_driver(stli_serial); - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { devfs_remove("staliomem/%d", i); + class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i)); + } devfs_remove("staliomem"); + class_simple_destroy(istallion_class); if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); @@ -5310,10 +5316,13 @@ "device\n"); devfs_mk_dir("staliomem"); + istallion_class = class_simple_create(THIS_MODULE, "staliomem"); for (i = 0; i < 4; i++) { devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "staliomem/%d", i); + class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), + NULL, "staliomem%d", i); } /* diff -Nru a/drivers/char/mem.c b/drivers/char/mem.c --- a/drivers/char/mem.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/mem.c Sun Apr 18 13:42:41 2004 @@ -410,7 +410,7 @@ if (count > size) count = size; - zap_page_range(vma, addr, count); + zap_page_range(vma, addr, count, NULL); zeromap_page_range(vma, addr, count, PAGE_COPY); size -= count; diff -Nru a/drivers/char/stallion.c b/drivers/char/stallion.c --- a/drivers/char/stallion.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/stallion.c Sun Apr 18 13:42:41 2004 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -732,6 +733,8 @@ /*****************************************************************************/ +static struct class_simple *stallion_class; + #ifdef MODULE /* @@ -788,12 +791,15 @@ restore_flags(flags); return; } - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { devfs_remove("staliomem/%d", i); + class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i)); + } devfs_remove("staliomem"); if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); + class_simple_destroy(stallion_class); if (stl_tmpwritebuf != (char *) NULL) kfree(stl_tmpwritebuf); @@ -3181,10 +3187,12 @@ printk("STALLION: failed to register serial board device\n"); devfs_mk_dir("staliomem"); + stallion_class = class_simple_create(THIS_MODULE, "staliomem"); for (i = 0; i < 4; i++) { devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR|S_IRUSR|S_IWUSR, "staliomem/%d", i); + class_simple_device_add(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); } stl_serial->owner = THIS_MODULE; diff -Nru a/drivers/char/tipar.c b/drivers/char/tipar.c --- a/drivers/char/tipar.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/tipar.c Sun Apr 18 13:42:41 2004 @@ -67,7 +67,7 @@ /* * Version Information */ -#define DRIVER_VERSION "1.17" +#define DRIVER_VERSION "1.19" #define DRIVER_AUTHOR "Romain Lievin " #define DRIVER_DESC "Device driver for TI/PC parallel link cables" #define DRIVER_LICENSE "GPL" @@ -361,10 +361,13 @@ switch (cmd) { case IOCTL_TIPAR_DELAY: - delay = (int)arg; //get_user(delay, &arg); - break; + delay = (int)arg; //get_user(delay, &arg); + break; case IOCTL_TIPAR_TIMEOUT: - timeout = (int)arg; //get_user(timeout, &arg); + if (arg != 0) + timeout = (int)arg; + else + retval = -EINVAL; break; default: retval = -ENOTTY; @@ -399,7 +402,10 @@ str = get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] > 0) { - timeout = ints[1]; + if (ints[1] != 0) + timeout = ints[1]; + else + printk("tipar: wrong timeout value (0), using default value instead."); if (ints[0] > 1) { delay = ints[2]; } diff -Nru a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c --- a/drivers/char/tpqic02.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/tpqic02.c Sun Apr 18 13:42:41 2004 @@ -94,6 +94,7 @@ #include #include #include +#include #include #include @@ -229,6 +230,8 @@ "600" /* untested. */ }; +static struct class_simple *tpqic02_class; + /* `exception_list' is needed for exception status reporting. * Exceptions 1..14 are defined by QIC-02 rev F. @@ -2696,23 +2699,32 @@ return -ENODEV; } + tpqic02_class = class_simple_create(THIS_MODULE, TPQIC02_NAME); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 2), NULL, "ntpqic11"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 2), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "ntpqic11"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 3), NULL, "tpqic11"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 3), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "tpqic11"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 4), NULL, "ntpqic24"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 4), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "ntpqic24"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 5), NULL, "tpqic24"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 5), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "tpqic24"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 6), NULL, "ntpqic20"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 6), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "ntpqic120"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 7), NULL, "tpqic20"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 7), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "tpqic120"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 8), NULL, "ntpqic50"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 8), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "ntpqic150"); + class_simple_device_add(tpqic02_class, MKDEV(QIC02_TAPE_MAJOR, 9), NULL, "tpqic50"); devfs_mk_cdev(MKDEV(QIC02_TAPE_MAJOR, 9), S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, "tpqic150"); @@ -2757,13 +2769,23 @@ qic02_release_resources(); devfs_remove("ntpqic11"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 2)); devfs_remove("tpqic11"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 3)); devfs_remove("ntpqic24"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 4)); devfs_remove("tpqic24"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 5)); devfs_remove("ntpqic120"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 6)); devfs_remove("tpqic120"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 7)); devfs_remove("ntpqic150"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 8)); devfs_remove("tpqic150"); + class_simple_device_remove(MKDEV(QIC02_TAPE_MAJOR, 9)); + + class_simple_destroy(tpqic02_class); } static int qic02_module_init(void) diff -Nru a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c --- a/drivers/char/vc_screen.c Sun Apr 18 13:42:40 2004 +++ b/drivers/char/vc_screen.c Sun Apr 18 13:42:40 2004 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -469,6 +470,8 @@ .open = vcs_open, }; +static struct class_simple *vc_class; + void vcs_make_devfs(struct tty_struct *tty) { devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1), @@ -477,19 +480,26 @@ devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a%u", tty->index + 1); + class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1); + class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1); } void vcs_remove_devfs(struct tty_struct *tty) { devfs_remove("vcc/%u", tty->index + 1); devfs_remove("vcc/a%u", tty->index + 1); + class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1)); + class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129)); } int __init vcs_init(void) { if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); + vc_class = class_simple_create(THIS_MODULE, "vc"); devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0"); devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0"); + class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); return 0; } diff -Nru a/drivers/char/vt.c b/drivers/char/vt.c --- a/drivers/char/vt.c Sun Apr 18 13:42:41 2004 +++ b/drivers/char/vt.c Sun Apr 18 13:42:41 2004 @@ -2617,6 +2617,8 @@ int __init vty_init(void) { + vcs_init(); + console_driver = alloc_tty_driver(MAX_NR_CONSOLES); if (!console_driver) panic("Couldn't allocate console driver\n"); @@ -2644,7 +2646,6 @@ #ifdef CONFIG_FRAMEBUFFER_CONSOLE fb_console_init(); #endif - vcs_init(); return 0; } diff -Nru a/drivers/firmware/edd.c b/drivers/firmware/edd.c --- a/drivers/firmware/edd.c Sun Apr 18 13:42:40 2004 +++ b/drivers/firmware/edd.c Sun Apr 18 13:42:40 2004 @@ -125,13 +125,15 @@ static ssize_t edd_show_host_bus(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; int i; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } for (i = 0; i < 4; i++) { if (isprint(info->params.host_bus_type[i])) { @@ -169,13 +171,15 @@ static ssize_t edd_show_interface(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; int i; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } for (i = 0; i < 8; i++) { if (isprint(info->params.interface_type[i])) { @@ -231,11 +235,13 @@ static ssize_t edd_show_raw_data(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; ssize_t len = sizeof (info->params); - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) len = info->params.length; @@ -251,11 +257,13 @@ static ssize_t edd_show_version(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += scnprintf(p, left, "0x%02x\n", info->version); return (p - buf); @@ -272,11 +280,13 @@ static ssize_t edd_show_extensions(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) { p += scnprintf(p, left, "Fixed disk access\n"); @@ -296,11 +306,13 @@ static ssize_t edd_show_info_flags(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } if (info->params.info_flags & EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT) p += scnprintf(p, left, "DMA boundary error transparent\n"); @@ -324,11 +336,13 @@ static ssize_t edd_show_legacy_cylinders(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += snprintf(p, left, "0x%x\n", info->legacy_cylinders); return (p - buf); @@ -337,11 +351,13 @@ static ssize_t edd_show_legacy_heads(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += snprintf(p, left, "0x%x\n", info->legacy_heads); return (p - buf); @@ -350,11 +366,13 @@ static ssize_t edd_show_legacy_sectors(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += snprintf(p, left, "0x%x\n", info->legacy_sectors); return (p - buf); @@ -363,11 +381,13 @@ static ssize_t edd_show_default_cylinders(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += scnprintf(p, left, "0x%x\n", info->params.num_default_cylinders); return (p - buf); @@ -376,11 +396,13 @@ static ssize_t edd_show_default_heads(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += scnprintf(p, left, "0x%x\n", info->params.num_default_heads); return (p - buf); @@ -389,11 +411,13 @@ static ssize_t edd_show_default_sectors_per_track(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += scnprintf(p, left, "0x%x\n", info->params.sectors_per_track); return (p - buf); @@ -402,11 +426,13 @@ static ssize_t edd_show_sectors(struct edd_device *edev, char *buf) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; char *p = buf; - if (!edev || !info || !buf) { + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info || !buf) return -EINVAL; - } p += scnprintf(p, left, "0x%llx\n", info->params.number_of_sectors); return (p - buf); @@ -426,8 +452,11 @@ static int edd_has_legacy_cylinders(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->legacy_cylinders > 0; } @@ -435,8 +464,11 @@ static int edd_has_legacy_heads(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->legacy_heads > 0; } @@ -444,8 +476,11 @@ static int edd_has_legacy_sectors(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->legacy_sectors > 0; } @@ -453,8 +488,11 @@ static int edd_has_default_cylinders(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->params.num_default_cylinders > 0; } @@ -462,8 +500,11 @@ static int edd_has_default_heads(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->params.num_default_heads > 0; } @@ -471,8 +512,11 @@ static int edd_has_default_sectors_per_track(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return -EINVAL; + info = edd_dev_get_info(edev); + if (!info) return -EINVAL; return info->params.sectors_per_track > 0; } @@ -480,11 +524,14 @@ static int edd_has_edd30(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; int i, nonzero_path = 0; char c; - if (!edev || !info) + if (!edev) + return 0; + info = edd_dev_get_info(edev); + if (!info) return 0; if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { @@ -508,8 +555,11 @@ static int edd_has_disk80_sig(struct edd_device *edev) { - struct edd_info *info = edd_dev_get_info(edev); - if (!edev || !info) + struct edd_info *info; + if (!edev) + return 0; + info = edd_dev_get_info(edev); + if (!info) return 0; return info->device == 0x80; } @@ -597,9 +647,12 @@ static int edd_dev_is_type(struct edd_device *edev, const char *type) { - struct edd_info *info = edd_dev_get_info(edev); + struct edd_info *info; + if (!edev) + return 0; + info = edd_dev_get_info(edev); - if (edev && type && info) { + if (type && info) { if (!strncmp(info->params.host_bus_type, type, strlen(type)) || !strncmp(info->params.interface_type, type, strlen(type))) return 1; diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c --- a/drivers/ide/ide-probe.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ide/ide-probe.c Sun Apr 18 13:42:41 2004 @@ -103,7 +103,8 @@ if (id->config == 0x848a) return 1; /* CompactFlash */ if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ - || !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */ + || !strncmp(id->model, "SunDisk SDCFB", 13) /* old SanDisk */ + || !strncmp(id->model, "SanDisk SDCFB", 13) /* SanDisk */ || !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */ || !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */ || !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */ diff -Nru a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig --- a/drivers/ieee1394/Kconfig Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/Kconfig Sun Apr 18 13:42:40 2004 @@ -124,7 +124,7 @@ config IEEE1394_ETH1394 tristate "Ethernet over 1394" - depends on IEEE1394 && EXPERIMENTAL + depends on IEEE1394 && EXPERIMENTAL && INET select IEEE1394_CONFIG_ROM_IP1394 select IEEE1394_EXTRA_CONFIG_ROMS help diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c --- a/drivers/ieee1394/amdtp.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/amdtp.c Sun Apr 18 13:42:41 2004 @@ -319,7 +319,7 @@ control = reg_read(ohci, OHCI1394_IsoXmitContextControlSet + ctx * 16); if ((control & OHCI1394_CONTEXT_ACTIVE) == 0) break; - + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); } @@ -408,7 +408,7 @@ /* Now that we know the list is non-empty, we can get the head * of the list without locking, because the process context - * only adds to the tail. + * only adds to the tail. */ pl = list_entry(s->dma_packet_lists.next, struct packet_list, link); last = &pl->packets[PACKET_LIST_SIZE - 1]; @@ -424,7 +424,7 @@ if (last->db->payload_desc.status == 0) { HPSB_INFO("weird interrupt..."); return; - } + } /* If the last descriptor block does not specify a branch * address, we have a sample underflow. @@ -469,7 +469,7 @@ return &s->current_packet_list->packets[s->current_packet]; } - + static void stream_queue_packet(struct stream *s) { s->current_packet++; @@ -543,13 +543,13 @@ DMA_CTL_OUTPUT_MORE | DMA_CTL_IMMEDIATE | 8; if (next) { - p->db->payload_desc.control = + p->db->payload_desc.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH; p->db->payload_desc.branch = next->db_bus | 3; p->db->header_desc.skip = next->db_bus | 3; } else { - p->db->payload_desc.control = + p->db->payload_desc.control = DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH | DMA_CTL_UPDATE | DMA_CTL_IRQ; p->db->payload_desc.branch = 0; @@ -580,7 +580,7 @@ for (i = 0; i < PACKET_LIST_SIZE; i++) { if (i < PACKET_LIST_SIZE - 1) next = &pl->packets[i + 1]; - else + else next = NULL; packet_initialize(&pl->packets[i], next); } @@ -695,7 +695,7 @@ case AMDTP_FORMAT_IEC958_PCM: case AMDTP_FORMAT_IEC958_AC3: return get_iec958_header_bits(s, sub_frame, sample); - + case AMDTP_FORMAT_RAW: return 0x40; @@ -739,18 +739,18 @@ /* Fill IEEE1394 headers */ packet->db->header_desc.header[0] = - (IEEE1394_SPEED_100 << 16) | (0x01 << 14) | + (IEEE1394_SPEED_100 << 16) | (0x01 << 14) | (s->iso_channel << 8) | (TCODE_ISO_DATA << 4); packet->db->header_desc.header[1] = size << 16; - + /* Calculate synchronization timestamp (syt). First we * determine syt_index, that is, the index in the packet of * the sample for which the timestamp is valid. */ syt_index = (s->syt_interval - s->dbc) & (s->syt_interval - 1); if (syt_index < nevents) { - syt = ((atomic_read(&s->cycle_count) << 12) | + syt = ((atomic_read(&s->cycle_count) << 12) | s->cycle_offset.integer) & 0xffff; - fraction_add(&s->cycle_offset, + fraction_add(&s->cycle_offset, &s->cycle_offset, &s->ticks_per_syt_offset); /* This next addition should be modulo 8000 (0x1f40), @@ -763,7 +763,7 @@ syt = 0xffff; atomic_inc(&s->cycle_count2); - + /* Fill cip header */ packet->payload->eoh0 = 0; packet->payload->sid = s->host->host->node_id & 0x3f; @@ -1072,7 +1072,7 @@ * that sometimes generates an it transmit interrupt if we * later re-enable the context. */ - wait_event_interruptible(s->packet_list_wait, + wait_event_interruptible(s->packet_list_wait, list_empty(&s->dma_packet_lists)); ohci1394_stop_it_ctx(s->host->ohci, s->iso_tasklet.context, 1); @@ -1102,7 +1102,7 @@ unsigned char *p; int i; size_t length; - + if (s->packet_pool == NULL) return -EBADFD; @@ -1123,16 +1123,16 @@ return -EFAULT; if (s->input->length < s->input->size) continue; - + stream_flush(s); - + if (s->current_packet_list != NULL) continue; if (file->f_flags & O_NONBLOCK) return i + length > 0 ? i + length : -EAGAIN; - if (wait_event_interruptible(s->packet_list_wait, + if (wait_event_interruptible(s->packet_list_wait, !list_empty(&s->free_packet_lists))) return -EINTR; } @@ -1152,7 +1152,7 @@ case AMDTP_IOC_CHANNEL: if (copy_from_user(&cfg, (struct amdtp_ioctl *) arg, sizeof cfg)) return -EFAULT; - else + else return stream_configure(s, cmd, &cfg); default: @@ -1266,6 +1266,7 @@ { cdev_init(&amdtp_cdev, &amdtp_fops); amdtp_cdev.owner = THIS_MODULE; + kobject_set_name(&amdtp_cdev.kobj, "amdtp"); if (cdev_add(&amdtp_cdev, IEEE1394_AMDTP_DEV, 16)) { HPSB_ERR("amdtp: unable to add char device"); return -EIO; diff -Nru a/drivers/ieee1394/amdtp.h b/drivers/ieee1394/amdtp.h --- a/drivers/ieee1394/amdtp.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/amdtp.h Sun Apr 18 13:42:40 2004 @@ -24,7 +24,7 @@ * * The dimension field specifies the dimension of the signal, that is, * the number of audio channels. Only AMDTP_FORMAT_RAW supports - * settings greater than 2. + * settings greater than 2. * * The mode field specifies which transmission mode to use. The AMDTP * specifies two different transmission modes: blocking and diff -Nru a/drivers/ieee1394/cmp.c b/drivers/ieee1394/cmp.c --- a/drivers/ieee1394/cmp.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/cmp.c Sun Apr 18 13:42:41 2004 @@ -187,14 +187,14 @@ int csraddr = addr - CSR_REGISTER_BASE; int plug; struct cmp_host *ch; - + if (length != 4) return RCODE_TYPE_ERROR; ch = hpsb_get_hostinfo(&cmp_highlevel, host); if (csraddr == 0x900) { *buf = cpu_to_be32(ch->u.ompr_quadlet); - return RCODE_COMPLETE; + return RCODE_COMPLETE; } else if (csraddr < 0x904 + ch->u.ompr.nplugs * 4) { plug = (csraddr - 0x904) / 4; @@ -206,7 +206,7 @@ } else if (csraddr == 0x980) { *buf = cpu_to_be32(ch->v.impr_quadlet); - return RCODE_COMPLETE; + return RCODE_COMPLETE; } else if (csraddr < 0x984 + ch->v.impr.nplugs * 4) { plug = (csraddr - 0x984) / 4; @@ -225,10 +225,10 @@ struct cmp_host *ch; ch = hpsb_get_hostinfo(&cmp_highlevel, host); - - if (extcode != EXTCODE_COMPARE_SWAP) + + if (extcode != EXTCODE_COMPARE_SWAP) return RCODE_TYPE_ERROR; - + if (csraddr == 0x900) { /* FIXME: Ignore writes to bits 30-31 and 0-7 */ *store = cpu_to_be32(ch->u.ompr_quadlet); diff -Nru a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c --- a/drivers/ieee1394/csr.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/csr.c Sun Apr 18 13:42:40 2004 @@ -130,23 +130,23 @@ host->csr.state &= ~0x100; } - host->csr.topology_map[1] = + host->csr.topology_map[1] = cpu_to_be32(be32_to_cpu(host->csr.topology_map[1]) + 1); - host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16 + host->csr.topology_map[2] = cpu_to_be32(host->node_count << 16 | host->selfid_count); - host->csr.topology_map[0] = + host->csr.topology_map[0] = cpu_to_be32((host->selfid_count + 2) << 16 | csr_crc16(host->csr.topology_map + 1, host->selfid_count + 2)); - host->csr.speed_map[1] = + host->csr.speed_map[1] = cpu_to_be32(be32_to_cpu(host->csr.speed_map[1]) + 1); - host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16 + host->csr.speed_map[0] = cpu_to_be32(0x3f1 << 16 | csr_crc16(host->csr.speed_map+1, 0x3f1)); } -/* +/* * HI == seconds (bits 0:2) * LO == fraction units of 1/8000 of a second, as per 1394 (bits 19:31) * @@ -161,7 +161,7 @@ static inline void calculate_expire(struct csr_control *csr) { unsigned long units; - + /* Take the seconds, and convert to units */ units = (unsigned long)(csr->split_timeout_hi & 0x07) << 13; @@ -288,7 +288,7 @@ } -int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom, +int hpsb_update_config_rom(struct hpsb_host *host, const quadlet_t *new_rom, size_t buffersize, unsigned char rom_version) { unsigned long flags; @@ -296,7 +296,7 @@ HPSB_NOTICE("hpsb_update_config_rom() is deprecated"); - spin_lock_irqsave(&host->csr.lock, flags); + spin_lock_irqsave(&host->csr.lock, flags); if (rom_version != host->csr.generation) ret = -1; else if (buffersize > host->csr.rom->cache_head->size) @@ -329,10 +329,10 @@ int csraddr = addr - CSR_REGISTER_BASE; const char *src; - spin_lock_irqsave(&host->csr.lock, flags); + spin_lock_irqsave(&host->csr.lock, flags); if (csraddr < CSR_SPEED_MAP) { - src = ((char *)host->csr.topology_map) + csraddr + src = ((char *)host->csr.topology_map) + csraddr - CSR_TOPOLOGY_MAP; } else { src = ((char *)host->csr.speed_map) + csraddr - CSR_SPEED_MAP; @@ -352,7 +352,7 @@ int csraddr = addr - CSR_REGISTER_BASE; int oldcycle; quadlet_t ret; - + if ((csraddr | length) & 0x3) return RCODE_TYPE_ERROR; @@ -404,7 +404,7 @@ /* cycle time wrapped around */ host->csr.bus_time += (1 << 7); } - *(buf++) = cpu_to_be32(host->csr.bus_time + *(buf++) = cpu_to_be32(host->csr.bus_time | (host->csr.cycle_time >> 25)); out; @@ -464,7 +464,7 @@ quadlet_t *data, u64 addr, size_t length, u16 flags) { int csraddr = addr - CSR_REGISTER_BASE; - + if ((csraddr | length) & 0x3) return RCODE_TYPE_ERROR; @@ -494,12 +494,12 @@ return RCODE_ADDRESS_ERROR; case CSR_SPLIT_TIMEOUT_HI: - host->csr.split_timeout_hi = + host->csr.split_timeout_hi = be32_to_cpu(*(data++)) & 0x00000007; calculate_expire(&host->csr); out; case CSR_SPLIT_TIMEOUT_LO: - host->csr.split_timeout_lo = + host->csr.split_timeout_lo = be32_to_cpu(*(data++)) & 0xfff80000; calculate_expire(&host->csr); out; diff -Nru a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c --- a/drivers/ieee1394/csr1212.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/csr1212.c Sun Apr 18 13:42:41 2004 @@ -1,6 +1,6 @@ /* * csr1212.c -- IEEE 1212 Control and Status Register support for Linux - * + * * Copyright (C) 2003 Francois Retief * Steve Kinneberg * @@ -173,7 +173,7 @@ if (!csr) return NULL; - csr->cache_head = + csr->cache_head = csr1212_rom_cache_malloc(CSR1212_CONFIG_ROM_SPACE_OFFSET, CSR1212_CONFIG_ROM_SPACE_SIZE); if (!csr->cache_head) { @@ -238,7 +238,7 @@ struct csr1212_keyval *csr1212_new_immediate(u_int8_t key, u_int32_t value) { struct csr1212_keyval *kv = csr1212_new_keyval(CSR1212_KV_TYPE_IMMEDIATE, key); - + if (!kv) return NULL; @@ -253,11 +253,10 @@ if (!kv) return NULL; - + if (data_len > 0) { kv->value.leaf.data = CSR1212_MALLOC(data_len); - if (!kv->value.leaf.data) - { + if (!kv->value.leaf.data) { CSR1212_FREE(kv); return NULL; } @@ -572,7 +571,7 @@ CSR1212_MODIFIABLE_DESCRIPTOR_SET_MAX_SIZE(kv, max_size); CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_HI(kv, address); CSR1212_MODIFIABLE_DESCRIPTOR_SET_ADDRESS_LO(kv, address); - + return kv; } @@ -621,7 +620,7 @@ /* make sure last quadlet is zeroed out */ *((u_int32_t*)&(buffer[(data_len - 1) & ~0x3])) = 0; - + /* Copy keyword(s) into leaf data buffer */ for (i = 0; i < strc; i++) { int len = strlen(strv[i]) + 1; @@ -643,7 +642,7 @@ return; dentry = csr1212_find_keyval(dir, kv); - + if (!dentry) return; @@ -788,8 +787,7 @@ return CSR1212_ENOMEM; } - if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) != CSR1212_SUCCESS) - { + if (csr1212_attach_keyval_to_directory(csr->root_kv, cache->ext_rom) != CSR1212_SUCCESS) { csr1212_release_keyval(cache->ext_rom); csr->ops->release_addr(csr_addr, csr->private); CSR1212_FREE(cache); @@ -1119,12 +1117,11 @@ /* Remove unused, excess cache regions */ while (cache) { struct csr1212_csr_rom_cache *oc = cache; - + cache = cache->next; csr1212_remove_cache(csr, oc); } - /* Go through the list backward so that when done, the correct CRC * will be calculated for the Extended ROM areas. */ for(cache = csr->cache_tail; cache; cache = cache->prev) { @@ -1263,7 +1260,7 @@ ret = CSR1212_ENOMEM; goto fail; } - + k->refcnt = 0; /* Don't keep local reference when parsing. */ break; @@ -1450,7 +1447,7 @@ newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!newcr) return CSR1212_ENOMEM; - + newcr->offset_start = cache_index & ~(csr->max_rom - 1); newcr->offset_end = newcr->offset_start; newcr->next = cr; @@ -1474,7 +1471,7 @@ newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region)); if (!newcr) return CSR1212_ENOMEM; - + newcr->offset_start = cache_index & ~(csr->max_rom - 1); newcr->offset_end = newcr->offset_start; newcr->prev = cr; diff -Nru a/drivers/ieee1394/csr1212.h b/drivers/ieee1394/csr1212.h --- a/drivers/ieee1394/csr1212.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/csr1212.h Sun Apr 18 13:42:40 2004 @@ -1,6 +1,6 @@ /* * csr1212.h -- IEEE 1212 Control and Status Register support for Linux - * + * * Copyright (C) 2003 Francois Retief * Steve Kinneberg * @@ -37,6 +37,7 @@ #include #include #include +#include #define CSR1212_MALLOC(size) kmalloc((size), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) #define CSR1212_FREE(ptr) kfree(ptr) @@ -440,7 +441,7 @@ static const int pd[4] = { 0, 4, 16, 256 }; static const int cs[16] = { 4, 2 }; int ps = pd[CSR1212_ICON_DESCRIPTOR_LEAF_PALETTE_DEPTH(kv)]; - + return &kv->value.leaf.data[5 + (ps * cs[CSR1212_ICON_DESCRIPTOR_LEAF_COLOR_SPACE(kv)]) / sizeof(u_int32_t)]; @@ -705,7 +706,7 @@ * _kv is a struct csr1212_keyval * that'll point to the current keyval (loop index). * _dir is a struct csr1212_keyval * that points to the directory to be looped. * _pos is a struct csr1212_dentry * that is used internally for indexing. - * + * * kv will be NULL upon exit of the loop. */ #define csr1212_for_each_dir_entry(_csr, _kv, _dir, _pos) \ diff -Nru a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c --- a/drivers/ieee1394/dma.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/dma.c Sun Apr 18 13:42:41 2004 @@ -96,7 +96,7 @@ /* fill scatter/gather list with pages */ for (i = 0; i < dma->n_pages; i++) { unsigned long va = (unsigned long) dma->kvirt + (i << PAGE_SHIFT); - + dma->sglist[i].page = vmalloc_to_page((void *)va); dma->sglist[i].length = PAGE_SIZE; } @@ -196,6 +196,8 @@ pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], last - first + 1, dma->direction); } +#ifdef CONFIG_MMU + /* nopage() handler for mmap access */ static struct page* @@ -251,3 +253,12 @@ return 0; } + +#else /* CONFIG_MMU */ + +int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma) +{ + return -EINVAL; +} + +#endif /* CONFIG_MMU */ diff -Nru a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h --- a/drivers/ieee1394/dma.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/dma.h Sun Apr 18 13:42:41 2004 @@ -14,7 +14,7 @@ #include /* struct dma_prog_region - + a small, physically-contiguous DMA buffer with random-access, synchronous usage characteristics */ @@ -37,7 +37,7 @@ } /* struct dma_region - + a large, non-physically-contiguous DMA buffer with streaming, asynchronous usage characteristics */ diff -Nru a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h --- a/drivers/ieee1394/dv1394-private.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/dv1394-private.h Sun Apr 18 13:42:41 2004 @@ -34,11 +34,11 @@ /* none of this is exposed to user-space */ -/* +/* the 8-byte CIP (Common Isochronous Packet) header that precedes each packet of DV data. - See the IEC 61883 standard. + See the IEC 61883 standard. */ struct CIP_header { unsigned char b[8]; }; @@ -71,10 +71,10 @@ -/* +/* DMA commands used to program the OHCI's DMA engine - See the Texas Instruments OHCI 1394 chipset documentation. + See the Texas Instruments OHCI 1394 chipset documentation. */ struct output_more_immediate { u32 q[8]; }; @@ -95,17 +95,17 @@ omi->q[1] = 0; omi->q[2] = 0; omi->q[3] = 0; - + /* IT packet header */ omi->q[4] = cpu_to_le32( (0x0 << 16) /* IEEE1394_SPEED_100 */ | (tag << 14) | (channel << 8) - | (TCODE_ISO_DATA << 4) + | (TCODE_ISO_DATA << 4) | (sync_tag) ); /* reserved field; mimic behavior of my Sony DSR-40 */ omi->q[5] = cpu_to_le32((payload_size << 16) | (0x7F << 8) | 0xA0); - + omi->q[6] = 0; omi->q[7] = 0; } @@ -186,11 +186,11 @@ -/* +/* A "DMA descriptor block" consists of several contiguous DMA commands. - struct DMA_descriptor_block encapsulates all of the commands necessary - to send one packet of DV data. - + struct DMA_descriptor_block encapsulates all of the commands necessary + to send one packet of DV data. + There are three different types of these blocks: 1) command to send an empty packet (CIP header only, no DV data): @@ -225,44 +225,44 @@ union { struct { /* iso header, common to all output block types */ - struct output_more_immediate omi; - + struct output_more_immediate omi; + union { /* empty packet */ struct { struct output_last ol; /* CIP header */ } empty; - + /* full packet */ struct { struct output_more om; /* CIP header */ - + union { /* payload does not cross page boundary */ struct { struct output_last ol; /* data payload */ } nocross; - + /* payload crosses page boundary */ struct { struct output_more om; /* data payload */ struct output_last ol; /* data payload */ } cross; } u; - + } full; } u; } out; struct { - struct input_last il; + struct input_last il; } in; } u; - /* ensure that PAGE_SIZE % sizeof(struct DMA_descriptor_block) == 0 + /* ensure that PAGE_SIZE % sizeof(struct DMA_descriptor_block) == 0 by padding out to 128 bytes */ - u32 __pad__[12]; + u32 __pad__[12]; }; @@ -281,7 +281,7 @@ /* index of this frame in video_card->frames[] */ unsigned int frame_num; - /* FRAME_CLEAR - DMA program not set up, waiting for data + /* FRAME_CLEAR - DMA program not set up, waiting for data FRAME_READY - DMA program written, ready to transmit Changes to these should be locked against the interrupt @@ -290,7 +290,7 @@ FRAME_CLEAR = 0, FRAME_READY } state; - + /* whether this frame has been DMA'ed already; used only from the IRQ handler to determine whether the frame can be reset */ int done; @@ -299,7 +299,7 @@ /* kernel virtual pointer to the start of this frame's data in the user ringbuffer. Use only for CPU access; to get the DMA bus address you must go through the video->user_dma mapping */ - unsigned long data; + unsigned long data; /* Max # of packets per frame */ #define MAX_PACKETS 500 @@ -310,7 +310,7 @@ struct CIP_header *header_pool; dma_addr_t header_pool_dma; - + /* a physically contiguous memory pool for allocating DMA descriptor blocks; usually around 64KB in size !descriptor_pool must be aligned to PAGE_SIZE! */ @@ -338,7 +338,7 @@ /* pointer to the first packet's CIP header (where the timestamp goes) */ struct CIP_header *cip_syt1; - + /* pointer to the second packet's CIP header (only set if the first packet was empty) */ struct CIP_header *cip_syt2; @@ -384,7 +384,7 @@ static void frame_reset(struct frame *f); /* struct video_card contains all data associated with one instance - of the dv1394 driver + of the dv1394 driver */ enum modes { MODE_RECEIVE, @@ -411,7 +411,7 @@ u32 ohci_IsoXmitContextControlSet; u32 ohci_IsoXmitContextControlClear; u32 ohci_IsoXmitCommandPtr; - + /* OHCI card IR DMA context number, -1 if not in use */ struct ohci1394_iso_tasklet ir_tasklet; int ohci_ir_ctx; @@ -421,10 +421,10 @@ u32 ohci_IsoRcvContextControlClear; u32 ohci_IsoRcvCommandPtr; u32 ohci_IsoRcvContextMatch; - - + + /* CONCURRENCY CONTROL */ - + /* there are THREE levels of locking associated with video_card. */ /* @@ -435,7 +435,7 @@ */ unsigned long open; - /* + /* 2) the spinlock - this provides mutual exclusion between the interrupt handler and process-context operations. Generally you must take the spinlock under the following conditions: @@ -458,7 +458,7 @@ /* flag to prevent spurious interrupts (which OHCI seems to generate a lot :) from accessing the struct */ int dma_running; - + /* 3) the sleeping semaphore 'sem' - this is used from process context only, to serialize various operations on the video_card. Even though only one @@ -477,24 +477,24 @@ /* support asynchronous I/O signals (SIGIO) */ struct fasync_struct *fasync; - + /* the large, non-contiguous (rvmalloc()) ringbuffer for DV data, exposed to user-space via mmap() */ unsigned long dv_buf_size; struct dma_region dv_buf; - + /* next byte in the ringbuffer that a write() call will fill */ size_t write_off; struct frame *frames[DV1394_MAX_FRAMES]; - + /* n_frames also serves as an indicator that this struct video_card is initialized and ready to run DMA buffers */ int n_frames; /* this is the frame that is currently "owned" by the OHCI DMA controller - (set to -1 iff DMA is not running) + (set to -1 iff DMA is not running) ! must lock against the interrupt handler when accessing it ! @@ -511,7 +511,6 @@ The interrupt handler will NEVER advance active_frame to a frame that is not READY. - */ int active_frame; int first_run; @@ -521,10 +520,10 @@ /* altered ONLY from process context. Must check first_clear_frame->state; if it's READY, that means the ringbuffer is full with READY frames; if it's CLEAR, that means one or more ringbuffer frames are CLEAR */ - unsigned int first_clear_frame; + unsigned int first_clear_frame; /* altered both by process and interrupt */ - unsigned int n_clear_frames; + unsigned int n_clear_frames; /* only altered by the interrupt */ unsigned int dropped_frames; @@ -548,17 +547,17 @@ /* the isochronous channel to use, -1 if video card is inactive */ int channel; - + /* physically contiguous packet ringbuffer for receive */ struct dma_region packet_buf; unsigned long packet_buf_size; - + unsigned int current_packet; int first_frame; /* received first start frame marker? */ enum modes mode; }; -/* +/* if the video_card is not initialized, then the ONLY fields that are valid are: ohci open @@ -575,7 +574,7 @@ static void do_dv1394_shutdown(struct video_card *video, int free_user_buf); -/* NTSC empty packet rate accurate to within 0.01%, +/* NTSC empty packet rate accurate to within 0.01%, calibrated against a Sony DSR-40 DVCAM deck */ #define CIP_N_NTSC 68000000 diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c --- a/drivers/ieee1394/dv1394.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/dv1394.c Sun Apr 18 13:42:41 2004 @@ -47,11 +47,11 @@ TODO: - tunable frame-drop behavior: either loop last frame, or halt transmission - + - use a scatter/gather buffer for DMA programs (f->descriptor_pool) so that we don't rely on allocating 64KB of contiguous kernel memory via pci_alloc_consistent() - + DONE: - during reception, better handling of dropped frames and continuity errors - during reception, prevent DMA from bypassing the irq tasklets @@ -82,7 +82,7 @@ - expose NTSC and PAL as separate devices (can be overridden) */ - + #include #include #include @@ -117,7 +117,7 @@ #include "nodemgr.h" #include "hosts.h" #include "ieee1394_core.h" -#include "highlevel.h" +#include "highlevel.h" #include "dv1394.h" #include "dv1394-private.h" @@ -215,7 +215,7 @@ debug_printk("dv1394: frame_new: allocated CIP header pool at virt 0x%08lx (contig) dma 0x%08lx size %ld\n", (unsigned long) f->header_pool, (unsigned long) f->header_pool_dma, PAGE_SIZE); - + f->descriptor_pool_size = MAX_PACKETS * sizeof(struct DMA_descriptor_block); /* make it an even # of pages */ f->descriptor_pool_size += PAGE_SIZE - (f->descriptor_pool_size%PAGE_SIZE); @@ -228,10 +228,10 @@ kfree(f); return NULL; } - + debug_printk("dv1394: frame_new: allocated DMA program memory at virt 0x%08lx (contig) dma 0x%08lx size %ld\n", (unsigned long) f->descriptor_pool, (unsigned long) f->descriptor_pool_dma, f->descriptor_pool_size); - + f->data = 0; frame_reset(f); @@ -248,9 +248,9 @@ -/* +/* frame_prepare() - build the DMA program for transmitting - + Frame_prepare() must be called OUTSIDE the video->spinlock. However, frame_prepare() must still be serialized, so it should be called WITH the video->sem taken. @@ -265,7 +265,7 @@ dma_addr_t block_dma; struct CIP_header *cip; dma_addr_t cip_dma; - + unsigned int n_descriptors, full_packets, packets_per_frame, payload_size; /* these flags denote packets that need special attention */ @@ -278,7 +278,7 @@ unsigned long irq_flags; irq_printk("frame_prepare( %d ) ---------------------\n", this_frame); - + full_packets = 0; @@ -304,7 +304,7 @@ return; } - /* the block surely won't cross a page boundary, + /* the block surely won't cross a page boundary, since an even number of descriptor_blocks fit on a page */ block = &(f->descriptor_pool[f->n_packets]); @@ -312,22 +312,22 @@ to the kernel base address of the descriptor pool + DMA base address of the descriptor pool */ block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; - + /* the whole CIP pool fits on one page, so no worries about boundaries */ - if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) + if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) > PAGE_SIZE) { printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n"); return; } cip = &(f->header_pool[f->n_packets]); - + /* DMA address of the CIP header = offset of cip relative to kernel base address of the header pool + DMA base address of the header pool */ cip_dma = (unsigned long) cip % PAGE_SIZE + f->header_pool_dma; - + /* is this an empty packet? */ if (video->cip_accum > (video->cip_d - video->cip_n)) { @@ -362,7 +362,7 @@ for this purpose, because that would leave very little time to set the timestamp before DMA starts on the next frame. */ - + if (f->n_packets == 0) { first_packet = 1; } else if ( full_packets == (packets_per_frame-1) ) { @@ -370,7 +370,7 @@ } else if (f->n_packets == packets_per_frame) { mid_packet = 1; } - + /********************/ /* setup CIP header */ @@ -396,10 +396,10 @@ fill_cip_header(cip, /* the node ID number of the OHCI card */ reg_read(video->ohci, OHCI1394_NodeID) & 0x3F, - video->continuity_counter, + video->continuity_counter, video->pal_or_ntsc, 0xFFFF /* the timestamp is filled in later */); - + /* advance counter, only for full packets */ if ( ! empty_packet ) video->continuity_counter++; @@ -423,7 +423,7 @@ sizeof(struct CIP_header), /* data size */ cip_dma); - + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]); else if (mid_packet) @@ -445,7 +445,7 @@ sizeof(struct CIP_header), /* data size */ cip_dma); - + /* third (and possibly fourth) descriptor - for DV data */ /* the 480-byte payload can cross a page boundary; if so, we need to split it into two DMA descriptors */ @@ -464,9 +464,9 @@ data_p - (unsigned long) video->dv_buf.kvirt)); fill_output_last( &(block->u.out.u.full.u.cross.ol), - + /* want completion status on all interesting packets */ - (first_packet || mid_packet || last_packet) ? 1 : 0, + (first_packet || mid_packet || last_packet) ? 1 : 0, /* want interrupt on all interesting packets */ (first_packet || mid_packet || last_packet) ? 1 : 0, @@ -492,14 +492,14 @@ n_descriptors = 5; if (first_packet) f->first_n_descriptors = n_descriptors; - + full_packets++; } else { /* fits on one page */ fill_output_last( &(block->u.out.u.full.u.nocross.ol), - + /* want completion status on all interesting packets */ (first_packet || mid_packet || last_packet) ? 1 : 0, @@ -508,11 +508,11 @@ 480, /* data size (480 bytes of DV data) */ - + /* DMA address of data_p */ dma_region_offset_to_bus(&video->dv_buf, data_p - (unsigned long) video->dv_buf.kvirt)); - + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); else if (mid_packet) @@ -531,8 +531,8 @@ full_packets++; } } - - /* link this descriptor block into the DMA program by filling in + + /* link this descriptor block into the DMA program by filling in the branch address of the previous block */ /* note: we are not linked into the active DMA chain yet */ @@ -545,10 +545,10 @@ f->n_packets++; - + } - /* when we first assemble a new frame, set the final branch + /* when we first assemble a new frame, set the final branch to loop back up to the top */ *(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors); @@ -572,11 +572,11 @@ this_frame, video->active_frame, video->n_clear_frames, video->first_clear_frame, last_frame); irq_printk(" begin_ts %08lx mid_ts %08lx end_ts %08lx end_br %08lx\n", - (unsigned long) f->frame_begin_timestamp, - (unsigned long) f->mid_frame_timestamp, - (unsigned long) f->frame_end_timestamp, + (unsigned long) f->frame_begin_timestamp, + (unsigned long) f->mid_frame_timestamp, + (unsigned long) f->frame_end_timestamp, (unsigned long) f->frame_end_branch); - + if (video->active_frame != -1) { /* if DMA is already active, we are almost done */ @@ -589,7 +589,7 @@ /* this write MUST precede the next one, or we could silently drop frames */ wmb(); - + /* disable the want_status semaphore on the last packet */ temp = le32_to_cpu(*(video->frames[last_frame]->frame_end_branch - 2)); temp &= 0xF7CFFFFF; @@ -605,7 +605,7 @@ dropped frame. Hopefully this window is too small to really matter, and the consequence is rather harmless. */ - + irq_printk(" new frame %d linked onto DMA chain\n", this_frame); @@ -614,13 +614,13 @@ } } else { - + u32 transmit_sec, transmit_cyc; u32 ts_cyc, ts_off; /* DMA is stopped, so this is the very first frame */ video->active_frame = this_frame; - + /* set CommandPtr to address and size of first descriptor block */ reg_write(video->ohci, video->ohci_IsoXmitCommandPtr, video->frames[video->active_frame]->descriptor_pool_dma | @@ -641,7 +641,7 @@ transmit_sec += transmit_cyc/8000; transmit_cyc %= 8000; - + ts_off = ct_off; ts_cyc = transmit_cyc + 3; ts_cyc %= 8000; @@ -657,7 +657,7 @@ f->cip_syt2->b[6] = f->assigned_timestamp >> 8; f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF; } - + /* --- start DMA --- */ /* clear all bits in ContextControl register */ @@ -668,8 +668,8 @@ /* the OHCI card has the ability to start ISO transmission on a particular cycle (start-on-cycle). This way we can ensure that the first DV frame will have an accurate timestamp. - - However, start-on-cycle only appears to work if the OHCI card + + However, start-on-cycle only appears to work if the OHCI card is cycle master! Since the consequences of messing up the first timestamp are minimal*, just disable start-on-cycle for now. @@ -690,7 +690,7 @@ /* set the 'run' bit */ reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, 0x8000); flush_pci_write(video->ohci); - + /* --- DMA should be running now --- */ debug_printk(" Cycle = %4u ContextControl = %08x CmdPtr = %08x\n", @@ -715,19 +715,19 @@ i++; } - printk("set = %08x, cmdPtr = %08x\n", + printk("set = %08x, cmdPtr = %08x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet), reg_read(video->ohci, video->ohci_IsoXmitCommandPtr) ); - + if ( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { - printk("DMA did NOT go active after 20ms, event = %x\n", + printk("DMA did NOT go active after 20ms, event = %x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F); } else printk("DMA is RUNNING!\n"); } #endif - + } @@ -738,11 +738,11 @@ /*** RECEIVE FUNCTIONS *****************************************************/ -/* +/* frame method put_packet - map and copy the packet data to its location in the frame - based upon DIF section and sequence + map and copy the packet data to its location in the frame + based upon DIF section and sequence */ static void inline @@ -754,28 +754,28 @@ /* sanity check */ if (dif_sequence > 11 || dif_block > 149) return; - + switch (section_type) { case 0: /* 1 Header block */ memcpy( (void *) f->data + dif_sequence * 150 * 80, p->data, 480); break; - + case 1: /* 2 Subcode blocks */ memcpy( (void *) f->data + dif_sequence * 150 * 80 + (1 + dif_block) * 80, p->data, 480); break; - + case 2: /* 3 VAUX blocks */ memcpy( (void *) f->data + dif_sequence * 150 * 80 + (3 + dif_block) * 80, p->data, 480); break; - + case 3: /* 9 Audio blocks interleaved with video */ memcpy( (void *) f->data + dif_sequence * 150 * 80 + (6 + dif_block * 16) * 80, p->data, 480); break; - + case 4: /* 135 Video blocks interleaved with audio */ memcpy( (void *) f->data + dif_sequence * 150 * 80 + (7 + (dif_block / 15) + dif_block) * 80, p->data, 480); break; - + default: /* we can not handle any other data */ break; } @@ -786,25 +786,25 @@ { if (video->first_run == 1) { video->first_run = 0; - + /* start DMA once all of the frames are READY */ video->n_clear_frames = 0; video->first_clear_frame = -1; video->current_packet = 0; video->active_frame = 0; - + /* reset iso recv control register */ reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, 0xFFFFFFFF); wmb(); - + /* clear bufferFill, set isochHeader and speed (0=100) */ reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x40000000); - + /* match on all tags, listen on channel */ reg_write(video->ohci, video->ohci_IsoRcvContextMatch, 0xf0000000 | video->channel); - + /* address and first descriptor block + Z=1 */ - reg_write(video->ohci, video->ohci_IsoRcvCommandPtr, + reg_write(video->ohci, video->ohci_IsoRcvCommandPtr, video->frames[0]->descriptor_pool_dma | 1); /* Z=1 */ wmb(); @@ -813,13 +813,13 @@ /* run */ reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, 0x8000); flush_pci_write(video->ohci); - + debug_printk("dv1394: DMA started\n"); - + #if DV1394_DEBUG_LEVEL >= 2 { int i; - + for (i = 0; i < 1000; ++i) { mdelay(1); if (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { @@ -828,15 +828,14 @@ } } if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { - printk("DEAD, event = %x\n", + printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); } else printk("RUNNING!\n"); } #endif - } - else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { - debug_printk("DEAD, event = %x\n", + } else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + debug_printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); /* wake */ @@ -845,7 +844,7 @@ } -/* +/* receive_packets() - build the DMA program for receiving */ @@ -875,24 +874,24 @@ /* locate a descriptor block and packet from the buffer */ block = &(f->descriptor_pool[i]); block_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; - + data = ((struct packet*)video->packet_buf.kvirt) + f->frame_num * MAX_PACKETS + i; - data_dma = dma_region_offset_to_bus( &video->packet_buf, + data_dma = dma_region_offset_to_bus( &video->packet_buf, ((unsigned long) data - (unsigned long) video->packet_buf.kvirt) ); - + /* setup DMA descriptor block */ want_interrupt = ((i % (MAX_PACKETS/2)) == 0 || i == (MAX_PACKETS-1)); fill_input_last( &(block->u.in.il), want_interrupt, 512, data_dma); - + /* link descriptors */ last_branch_address = f->frame_end_branch; - + if (last_branch_address != NULL) *(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */ - + f->frame_end_branch = &(block->u.in.il.q[2]); } - + } /* next j */ spin_unlock_irqrestore(&video->spinlock, irq_flags); @@ -913,7 +912,7 @@ debug_printk("dv1394: initialising %d\n", video->id); if (init->api_version != DV1394_API_VERSION) return -EINVAL; - + /* first sanitize all the parameters */ if ( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) ) return -EINVAL; @@ -949,7 +948,7 @@ /* (the card should not be reset if the parameters are screwy) */ do_dv1394_shutdown(video, 0); - + /* try to claim the ISO channel */ spin_lock_irqsave(&video->ohci->IR_channel_lock, flags); if (video->ohci->ISO_channel_usage & chan_mask) { @@ -991,19 +990,19 @@ } video->syt_offset = init->syt_offset; - + /* find and claim DMA contexts on the OHCI card */ if (video->ohci_it_ctx == -1) { ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT, it_tasklet_func, (unsigned long) video); - if (ohci1394_register_iso_tasklet(video->ohci, &video->it_tasklet) < 0) { + if (ohci1394_register_iso_tasklet(video->ohci, &video->it_tasklet) < 0) { printk(KERN_ERR "dv1394: could not find an available IT DMA context\n"); retval = -EBUSY; goto err; } - + video->ohci_it_ctx = video->it_tasklet.context; debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx); } @@ -1020,7 +1019,7 @@ video->ohci_ir_ctx = video->ir_tasklet.context; debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx); } - + /* allocate struct frames */ for (i = 0; i < init->n_frames; i++) { video->frames[i] = frame_new(i, video); @@ -1037,14 +1036,14 @@ retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE); if (retval) goto err; - + video->dv_buf_size = new_buf_size; debug_printk("dv1394: Allocated %d frame buffers, total %u pages (%u DMA pages), %lu bytes\n", video->n_frames, video->dv_buf.n_pages, video->dv_buf.n_dma_pages, video->dv_buf_size); } - + /* set up the frame->data pointers */ for (i = 0; i < video->n_frames; i++) video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size; @@ -1054,17 +1053,17 @@ video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS; if (video->packet_buf_size % PAGE_SIZE) video->packet_buf_size += PAGE_SIZE - (video->packet_buf_size % PAGE_SIZE); - + retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size, video->ohci->dev, PCI_DMA_FROMDEVICE); if (retval) goto err; - - debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", + + debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", video->n_frames*MAX_PACKETS, video->packet_buf.n_pages, video->packet_buf.n_dma_pages, video->packet_buf_size); } - + /* set up register offsets for IT context */ /* IT DMA context registers are spaced 16 bytes apart */ video->ohci_IsoXmitContextControlSet = OHCI1394_IsoXmitContextControlSet+16*video->ohci_it_ctx; @@ -1085,7 +1084,7 @@ /* enable interrupts for IR context */ reg_write(video->ohci, OHCI1394_IsoRecvIntMaskSet, (1 << video->ohci_ir_ctx) ); debug_printk("dv1394: interrupts enabled for IR context %d\n", video->ohci_ir_ctx); - + return 0; err: @@ -1105,7 +1104,7 @@ /* the following are now set via devfs */ init.channel = video->channel; init.format = video->pal_or_ntsc; - init.cip_n = video->cip_n; + init.cip_n = video->cip_n; init.cip_d = video->cip_d; init.syt_offset = video->syt_offset; @@ -1135,17 +1134,17 @@ reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15)); reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15)); flush_pci_write(video->ohci); - + video->active_frame = -1; video->first_run = 1; - + /* wait until DMA really stops */ i = 0; while (i < 1000) { - + /* wait 0.1 millisecond */ - udelay(100); - + udelay(100); + if ( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { /* still active */ @@ -1155,10 +1154,10 @@ debug_printk("dv1394: stop_dma: DMA stopped safely after %d ms\n", i/10); break; } - + i++; } - + if (i == 1000) { printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); } @@ -1175,12 +1174,12 @@ static void do_dv1394_shutdown(struct video_card *video, int free_dv_buf) { int i; - + debug_printk("dv1394: shutdown...\n"); /* stop DMA if in progress */ stop_dma(video); - + /* release the DMA contexts */ if (video->ohci_it_ctx != -1) { video->ohci_IsoXmitContextControlSet = 0; @@ -1189,7 +1188,7 @@ /* disable interrupts for IT context */ reg_write(video->ohci, OHCI1394_IsoXmitIntMaskClear, (1 << video->ohci_it_ctx)); - + /* remove tasklet */ ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet); debug_printk("dv1394: IT context %d released\n", video->ohci_it_ctx); @@ -1215,16 +1214,16 @@ if (video->channel != -1) { u64 chan_mask; unsigned long flags; - + chan_mask = (u64)1 << video->channel; - + spin_lock_irqsave(&video->ohci->IR_channel_lock, flags); video->ohci->ISO_channel_usage &= ~(chan_mask); spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags); - + video->channel = -1; } - + /* free the frame structs */ for (i = 0; i < DV1394_MAX_FRAMES; i++) { if (video->frames[i]) @@ -1233,10 +1232,10 @@ } video->n_frames = 0; - + /* we can't free the DMA buffer unless it is guaranteed that no more user-space mappings exist */ - + if (free_dv_buf) { dma_region_free(&video->dv_buf); video->dv_buf_size = 0; @@ -1324,11 +1323,11 @@ { /* I just copied this code verbatim from Alan Cox's mouse driver example (linux/Documentation/DocBook/) */ - + struct video_card *video = file_to_video_card(file); - + int retval = fasync_helper(fd, file, on, &video->fasync); - + if (retval < 0) return retval; return 0; @@ -1362,19 +1361,19 @@ ret = 0; add_wait_queue(&video->waitq, &wait); - + while (count > 0) { /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt fires between the check and the schedule() */ - + set_current_state(TASK_INTERRUPTIBLE); - + spin_lock_irqsave(&video->spinlock, flags); - + target_frame = video->first_clear_frame; - + spin_unlock_irqrestore(&video->spinlock, flags); if (video->frames[target_frame]->state == FRAME_CLEAR) { @@ -1390,7 +1389,7 @@ if (cnt > count) cnt = count; - if (cnt <= 0) { + if (cnt <= 0) { /* no room left, gotta wait */ if (file->f_flags & O_NONBLOCK) { if (!ret) @@ -1404,7 +1403,7 @@ } schedule(); - + continue; /* start over from 'while(count > 0)...' */ } @@ -1423,7 +1422,7 @@ if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) frame_prepare(video, target_frame); } - + remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); up(&video->sem); @@ -1456,9 +1455,9 @@ return ret; } video->continuity_counter = -1; - + receive_packets(video); - + start_dma_receive(video); } @@ -1470,7 +1469,7 @@ /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt fires between the check and the schedule() */ - + set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&video->spinlock, flags); @@ -1494,7 +1493,7 @@ if (cnt > count) cnt = count; - if (cnt <= 0) { + if (cnt <= 0) { /* no room left, gotta wait */ if (file->f_flags & O_NONBLOCK) { if (!ret) @@ -1508,7 +1507,7 @@ } schedule(); - + continue; /* start over from 'while(count > 0)...' */ } @@ -1531,7 +1530,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); } } - + remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); up(&video->sem); @@ -1579,19 +1578,19 @@ ret = -EINVAL; goto out; } - + while (n_submit > 0) { add_wait_queue(&video->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); - + spin_lock_irqsave(&video->spinlock, flags); /* wait until video->first_clear_frame is really CLEAR */ while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) { spin_unlock_irqrestore(&video->spinlock, flags); - + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); @@ -1601,14 +1600,14 @@ schedule(); set_current_state(TASK_INTERRUPTIBLE); - + spin_lock_irqsave(&video->spinlock, flags); } spin_unlock_irqrestore(&video->spinlock, flags); remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); - + frame_prepare(video, video->first_clear_frame); n_submit--; @@ -1625,7 +1624,7 @@ ret = -EINVAL; goto out; } - + n_wait = (unsigned int) arg; /* since we re-run the last frame on underflow, we will @@ -1636,16 +1635,16 @@ ret = -EINVAL; goto out; } - + add_wait_queue(&video->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); - + spin_lock_irqsave(&video->spinlock, flags); while (video->n_clear_frames < n_wait) { - + spin_unlock_irqrestore(&video->spinlock, flags); - + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); @@ -1655,7 +1654,7 @@ schedule(); set_current_state(TASK_INTERRUPTIBLE); - + spin_lock_irqsave(&video->spinlock, flags); } @@ -1674,7 +1673,7 @@ ret = -EINVAL; goto out; } - + n_recv = (unsigned int) arg; /* at least one frame must be active */ @@ -1682,7 +1681,7 @@ ret = -EINVAL; goto out; } - + spin_lock_irqsave(&video->spinlock, flags); /* release the clear frames */ @@ -1693,7 +1692,7 @@ /* reset dropped_frames */ video->dropped_frames = 0; - + spin_unlock_irqrestore(&video->spinlock, flags); ret = 0; @@ -1706,11 +1705,11 @@ if (ret) goto out; } - + video->continuity_counter = -1; - + receive_packets(video); - + start_dma_receive(video); ret = 0; @@ -1765,7 +1764,7 @@ /* reset dropped_frames */ video->dropped_frames = 0; - + spin_unlock_irqrestore(&video->spinlock, flags); if (copy_to_user((void*)arg, &status, sizeof(status))) { @@ -1798,11 +1797,11 @@ has already been set to video by devfs */ if (file->private_data) { video = (struct video_card*) file->private_data; - + } else { /* look up the card by ID */ unsigned long flags; - + spin_lock_irqsave(&dv1394_cards_lock, flags); if (!list_empty(&dv1394_cards)) { struct video_card *p; @@ -1819,10 +1818,10 @@ debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file)); return -ENODEV; } - + file->private_data = (void*) video; } - + #ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN if ( test_and_set_bit(0, &video->open) ) { @@ -1845,7 +1844,7 @@ /* clean up async I/O users */ dv1394_fasync(-1, file, 0); - + /* give someone else a turn */ clear_bit(0, &video->open); @@ -1865,19 +1864,19 @@ if (!video->dma_running) goto out; - irq_printk("ContextControl = %08x, CommandPtr = %08x\n", + irq_printk("ContextControl = %08x, CommandPtr = %08x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet), reg_read(video->ohci, video->ohci_IsoXmitCommandPtr) ); - + if ( (video->ohci_it_ctx != -1) && (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { struct frame *f; unsigned int frame, i; - + if (video->active_frame == -1) frame = 0; else @@ -1901,7 +1900,7 @@ int prev_frame; struct frame *prev_f; - + /* don't reset, need this later *(f->frame_begin_timestamp) = 0; */ irq_printk(" BEGIN\n"); @@ -1910,11 +1909,11 @@ if (prev_frame == -1) prev_frame += video->n_frames; prev_f = video->frames[prev_frame]; - + /* make sure we can actually garbage collect this frame */ if ( (prev_f->state == FRAME_READY) && - prev_f->done && (!f->done) ) + prev_f->done && (!f->done) ) { frame_reset(prev_f); video->n_clear_frames++; @@ -1929,7 +1928,7 @@ f->done = 1; } - + /* see if we need to set the timestamp for the next frame */ if ( *(f->mid_frame_timestamp) ) { struct frame *next_frame; @@ -1957,9 +1956,9 @@ plus the length of the last frame sent, plus the syt latency */ ts_cyc = begin_ts & 0xF; /* advance one frame, plus syt latency (typically 2-3) */ - ts_cyc += f->n_packets + video->syt_offset ; + ts_cyc += f->n_packets + video->syt_offset ; - ts_off = 0; + ts_off = 0; ts_cyc += ts_off/3072; ts_off %= 3072; @@ -1986,14 +1985,12 @@ video->dropped_frames++; } - - } /* for (each frame) */ } if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_OUT); - + /* wake readers/writers/ioctl'ers */ wake_up_interruptible(&video->waitq); } @@ -2011,10 +2008,9 @@ if (!video->dma_running) goto out; - + if ( (video->ohci_ir_ctx != -1) && - (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) - { + (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { int sof=0; /* start-of-frame flag */ struct frame *f; @@ -2036,14 +2032,14 @@ dma_region_sync_for_cpu(&video->packet_buf, (unsigned long) p - (unsigned long) video->packet_buf.kvirt, sizeof(struct packet)); - + packet_length = le16_to_cpu(p->data_length); packet_time = le16_to_cpu(p->timestamp); - + irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet, - packet_time, packet_length, + packet_time, packet_length, p->data[0], p->data[1]); - + /* get the descriptor based on packet_buffer cursor */ f = video->frames[video->current_packet / MAX_PACKETS]; block = &(f->descriptor_pool[video->current_packet % MAX_PACKETS]); @@ -2053,14 +2049,14 @@ /* get the current frame */ f = video->frames[video->active_frame]; - + /* exclude empty packet */ if (packet_length > 8 && xferstatus == 0x11) { /* check for start of frame */ - /* DRD> Changed to check section type ([0]>>5==0) + /* DRD> Changed to check section type ([0]>>5==0) and dif sequence ([1]>>4==0) */ sof = ( (p->data[0] >> 5) == 0 && (p->data[1] >> 4) == 0); - + dbc = (int) (p->cip_h1 >> 24); if ( video->continuity_counter != -1 && dbc > ((video->continuity_counter + 1) % 256) ) { @@ -2071,12 +2067,12 @@ video->first_clear_frame = -1; } video->continuity_counter = dbc; - + if (!video->first_frame) { if (sof) { video->first_frame = 1; } - + } else if (sof) { /* close current frame */ frame_reset(f); /* f->state = STATE_CLEAR */ @@ -2089,7 +2085,7 @@ } if (video->first_clear_frame == -1) video->first_clear_frame = video->active_frame; - + /* get the next frame */ video->active_frame = (video->active_frame + 1) % video->n_frames; f = video->frames[video->active_frame]; @@ -2101,22 +2097,22 @@ /* open next frame */ f->state = FRAME_READY; } - + /* copy to buffer */ if (f->n_packets > (video->frame_size / 480)) { printk(KERN_ERR "frame buffer overflow during receive\n"); } - + frame_put_packet(f, p); - + } /* first_frame */ } - + /* stop, end of ready packets */ else if (xferstatus == 0) { break; } - + /* reset xferStatus & resCount */ block->u.in.il.q[3] = cpu_to_le32(512); @@ -2127,7 +2123,7 @@ next_dma = ((unsigned long) block - (unsigned long) f->descriptor_pool) + f->descriptor_pool_dma; next->u.in.il.q[0] |= 3 << 20; /* enable interrupt */ next->u.in.il.q[2] = 0; /* disable branch */ - + /* link previous to next */ prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1); f = video->frames[prev_i / MAX_PACKETS]; @@ -2145,20 +2141,20 @@ /* advance packet_buffer cursor */ video->current_packet = (video->current_packet + 1) % (MAX_PACKETS * video->n_frames); - + } /* for all packets */ - + wake = 1; /* why the hell not? */ - + } /* receive interrupt */ - + if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_IN); /* wake readers/writers/ioctl'ers */ wake_up_interruptible(&video->waitq); } - + out: spin_unlock(&video->spinlock); } @@ -2216,13 +2212,13 @@ printk(KERN_ERR "dv1394: cannot allocate video_card\n"); goto err; } - + memset(video, 0, sizeof(struct video_card)); - + video->ohci = ohci; /* lower 2 bits of id indicate which of four "plugs" per host */ - video->id = ohci->host->id << 2; + video->id = ohci->host->id << 2; if (format == DV1394_NTSC) video->id |= mode; else @@ -2234,16 +2230,16 @@ video->ohci_IsoXmitContextControlSet = 0; video->ohci_IsoXmitContextControlClear = 0; video->ohci_IsoXmitCommandPtr = 0; - + video->ohci_IsoRcvContextControlSet = 0; video->ohci_IsoRcvContextControlClear = 0; video->ohci_IsoRcvCommandPtr = 0; video->ohci_IsoRcvContextMatch = 0; - + video->n_frames = 0; /* flag that video is not initialized */ video->channel = 63; /* default to broadcast channel */ video->active_frame = -1; - + /* initialize the following */ video->pal_or_ntsc = format; video->cip_n = 0; /* 0 = use builtin default */ @@ -2270,7 +2266,7 @@ INIT_LIST_HEAD(&video->list); list_add_tail(&video->list, &dv1394_cards); spin_unlock_irqrestore(&dv1394_cards_lock, flags); - + if (devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394*16 + video->id), S_IFCHR|S_IRUGO|S_IWUGO, @@ -2281,7 +2277,7 @@ goto err_free; debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id); - + return 0; err_free: @@ -2293,7 +2289,7 @@ static void dv1394_un_init(struct video_card *video) { char buf[32]; - + /* obviously nobody has the driver open at this point */ do_dv1394_shutdown(video, 1); snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2), @@ -2305,13 +2301,13 @@ kfree(video); } - + static void dv1394_remove_host (struct hpsb_host *host) { struct video_card *video; unsigned long flags; int id = host->id; - + /* We only work with the OHCI-1394 driver */ if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) return; @@ -2355,7 +2351,7 @@ devfs_mk_dir("ieee1394/dv/host%d", id); devfs_mk_dir("ieee1394/dv/host%d/NTSC", id); devfs_mk_dir("ieee1394/dv/host%d/PAL", id); - + dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); dv1394_init(ohci, DV1394_PAL, MODE_RECEIVE); @@ -2373,7 +2369,7 @@ struct ti_ohci *ohci; struct video_card *video = NULL, *tmp_vid; unsigned long flags; - + /* We only work with the OHCI-1394 driver */ if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) return; @@ -2394,7 +2390,7 @@ if (!video) return; - + spin_lock_irqsave(&video->spinlock, flags); if (!video->dma_running) @@ -2403,7 +2399,7 @@ /* check IT context */ if (video->ohci_it_ctx != -1) { u32 ctx; - + ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet); /* if (RUN but not ACTIVE) */ @@ -2415,17 +2411,17 @@ /* to be safe, assume a frame has been dropped. User-space programs should handle this condition like an underflow. */ video->dropped_frames++; - + /* for some reason you must clear, then re-set the RUN bit to restart DMA */ - + /* clear RUN */ reg_write(video->ohci, video->ohci_IsoXmitContextControlClear, (1 << 15)); flush_pci_write(video->ohci); - + /* set RUN */ reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 15)); flush_pci_write(video->ohci); - + /* set the WAKE bit (just in case; this isn't strictly necessary) */ reg_write(video->ohci, video->ohci_IsoXmitContextControlSet, (1 << 12)); flush_pci_write(video->ohci); @@ -2435,11 +2431,11 @@ reg_read(video->ohci, video->ohci_IsoXmitCommandPtr)); } } - + /* check IR context */ if (video->ohci_ir_ctx != -1) { u32 ctx; - + ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet); /* if (RUN but not ACTIVE) */ @@ -2454,15 +2450,15 @@ /* for some reason you must clear, then re-set the RUN bit to restart DMA */ /* XXX this doesn't work for me, I can't get IR DMA to restart :[ */ - + /* clear RUN */ reg_write(video->ohci, video->ohci_IsoRcvContextControlClear, (1 << 15)); flush_pci_write(video->ohci); - + /* set RUN */ reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 15)); flush_pci_write(video->ohci); - + /* set the WAKE bit (just in case; this isn't strictly necessary) */ reg_write(video->ohci, video->ohci_IsoRcvContextControlSet, (1 << 12)); flush_pci_write(video->ohci); @@ -2475,7 +2471,7 @@ out: spin_unlock_irqrestore(&video->spinlock, flags); - + /* wake readers/writers/ioctl'ers */ wake_up_interruptible(&video->waitq); } @@ -2616,6 +2612,7 @@ cdev_init(&dv1394_cdev, &dv1394_fops); dv1394_cdev.owner = THIS_MODULE; + kobject_set_name(&dv1394_cdev.kobj, "dv1394"); ret = cdev_add(&dv1394_cdev, IEEE1394_DV1394_DEV, 16); if (ret) { printk(KERN_ERR "dv1394: unable to register character device\n"); diff -Nru a/drivers/ieee1394/dv1394.h b/drivers/ieee1394/dv1394.h --- a/drivers/ieee1394/dv1394.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/dv1394.h Sun Apr 18 13:42:41 2004 @@ -49,7 +49,7 @@ To set the DV output parameters (e.g. whether you want NTSC or PAL video), use the DV1394_INIT ioctl, passing in the parameters you want in a struct dv1394_init. - + Example 1: To play a raw .DV file: cat foo.DV > /dev/dv1394 (cat will use write() internally) @@ -72,9 +72,9 @@ 2) For more control over buffering, and to avoid unnecessary copies - of the DV data, you can use the more sophisticated the mmap() interface. - First, call the DV1394_INIT ioctl to specify your parameters, - including the number of frames in the ringbuffer. Then, calling mmap() + of the DV data, you can use the more sophisticated the mmap() interface. + First, call the DV1394_INIT ioctl to specify your parameters, + including the number of frames in the ringbuffer. Then, calling mmap() on the dv1394 device will give you direct access to the ringbuffer from which the DV card reads your frame data. @@ -99,7 +99,7 @@ *--------------------------------------* | CLEAR | DV data | DV data | CLEAR | *--------------------------------------* - + transmission goes in this direction --->>> @@ -110,10 +110,10 @@ will continue to transmit frame 2, and will increase the dropped_frames counter each time it repeats the transmission). - + If you called DV1394_GET_STATUS at this instant, you would receive the following values: - + n_frames = 4 active_frame = 1 first_clear_frame = 3 @@ -144,9 +144,9 @@ (checks of system call return values omitted for brevity; always check return values in your code!) - + while ( frames left ) { - + struct pollfd *pfd = ...; pfd->fd = dv1394_fd; @@ -154,12 +154,12 @@ pfd->events = POLLOUT | POLLIN; (OUT for transmit, IN for receive) (add other sources of I/O here) - + poll(pfd, 1, -1); (or select(); add a timeout if you want) if (pfd->revents) { struct dv1394_status status; - + ioctl(dv1394_fd, DV1394_GET_STATUS, &status); if (status.dropped_frames > 0) { @@ -183,7 +183,7 @@ should close the dv1394 file descriptor (and munmap() all ringbuffer mappings, if you are using them), then re-open the dv1394 device (and re-map the ringbuffer). - + */ @@ -215,7 +215,7 @@ struct dv1394_init { /* DV1394_API_VERSION */ unsigned int api_version; - + /* isochronous transmission channel to use */ unsigned int channel; @@ -227,7 +227,7 @@ enum pal_or_ntsc format; /* the following are used only for transmission */ - + /* set these to zero unless you want a non-default empty packet rate (see below) */ unsigned long cip_n; @@ -244,7 +244,7 @@ would imply a different size for the ringbuffer). If you need a different buffer size, simply close and re-open the device, then initialize it with your new settings. */ - + /* Q: What are cip_n and cip_d? */ /* @@ -261,13 +261,13 @@ The default empty packet insertion rate seems to work for many people; if your DV output is stable, you can simply ignore this discussion. However, we have exposed the empty packet rate as a parameter to support devices that - do not work with the default rate. + do not work with the default rate. The decision to insert an empty packet is made with a numerator/denominator algorithm. Empty packets are produced at an average rate of CIP_N / CIP_D. You can alter the empty packet rate by passing non-zero values for cip_n and cip_d to the INIT ioctl. - + */ diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c --- a/drivers/ieee1394/eth1394.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/eth1394.c Sun Apr 18 13:42:41 2004 @@ -1,6 +1,6 @@ /* * eth1394.c -- Ethernet driver for Linux IEEE-1394 Subsystem - * + * * Copyright (C) 2001-2003 Ben Collins * 2000 Bonin Franck * 2003 Steve Kinneberg @@ -89,7 +89,7 @@ #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 1175 $ Ben Collins "; + "$Rev: 1198 $ Ben Collins "; struct fragment_info { struct list_head list; @@ -216,7 +216,7 @@ /* This is called after an "ifup" */ static int ether1394_open (struct net_device *dev) { - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; int ret = 0; /* Something bad happened, don't even try */ @@ -278,7 +278,7 @@ static int ether1394_change_mtu(struct net_device *dev, int new_mtu) { - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; if ((new_mtu < 68) || (new_mtu > min(ETH1394_DATA_LEN, @@ -479,7 +479,7 @@ { unsigned long flags; int i; - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; struct hpsb_host *host = priv->host; u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3])); u16 maxpayload = 1 << (host->csr.max_rec + 1); @@ -652,7 +652,7 @@ static void ether1394_remove_host (struct hpsb_host *host) { struct eth1394_host_info *hi; - + hi = hpsb_get_hostinfo(ð1394_highlevel, host); if (hi != NULL) { struct eth1394_priv *priv = (struct eth1394_priv *)hi->dev->priv; @@ -660,7 +660,7 @@ hpsb_unregister_addrspace(ð1394_highlevel, host, priv->local_fifo); - if (priv->iso != NULL) + if (priv->iso != NULL) hpsb_iso_shutdown(priv->iso); if (hi->dev) { @@ -731,18 +731,16 @@ eth->h_proto = htons(type); - if (dev->flags & (IFF_LOOPBACK|IFF_NOARP)) - { + if (dev->flags & (IFF_LOOPBACK|IFF_NOARP)) { memset(eth->h_dest, 0, dev->addr_len); return(dev->hard_header_len); } - if (daddr) - { + if (daddr) { memcpy(eth->h_dest,daddr,dev->addr_len); return dev->hard_header_len; } - + return -dev->hard_header_len; } @@ -760,15 +758,15 @@ struct eth1394hdr *eth = (struct eth1394hdr *)skb->data; struct net_device *dev = skb->dev; - switch (eth->h_proto) - { + switch (eth->h_proto) { + #ifdef CONFIG_INET case __constant_htons(ETH_P_IP): return arp_find((unsigned char*)ð->h_dest, skb); -#endif +#endif default: ETH1394_PRINT(KERN_DEBUG, dev->name, - "unable to resolve type %04x addresses.\n", + "unable to resolve type %04x addresses.\n", eth->h_proto); break; } @@ -797,7 +795,7 @@ eth->h_proto = type; memcpy(eth->h_dest, neigh->ha, dev->addr_len); - + hh->hh_len = ETH1394_HLEN; return 0; } @@ -867,7 +865,7 @@ nodeid_t srcid, nodeid_t destid, u16 ether_type) { - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; u64 dest_hw; unsigned short ret = 0; @@ -1010,7 +1008,7 @@ } new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC); - if (!new) + if (!new) return -ENOMEM; new->offset = offset; @@ -1192,7 +1190,7 @@ purge_partial_datagram(pdgl->prev); pdg->sz--; } - + retval = new_partial_datagram(dev, pdgl, dgl, dg_size, buf + hdr_len, fg_off, fg_len); @@ -1374,7 +1372,7 @@ * arphdr) is the same format as the ip1394 header, so they overlap. The rest * needs to be munged a bit. The remainder of the arphdr is formatted based * on hwaddr len and ipaddr len. We know what they'll be, so it's easy to - * judge. + * judge. * * Now that the EUI is used for the hardware address all we need to do to make * this work for 1394 is to insert 2 quadlets that contain max_rec size, @@ -1452,7 +1450,7 @@ hdr->common.lf = ETH1394_HDR_LF_IF; hdr->sf.fg_off = 0; break; - + default: hdr->sf.fg_off += adj_max_payload; bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload); @@ -1499,7 +1497,7 @@ ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending " "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(host, node)); return -1; - } + } p->header[0] = (p->node_id << 16) | (p->tlabel << 10) | (1 << 8) | (TCODE_WRITEB << 4); @@ -1538,7 +1536,6 @@ { if (packet->tcode != TCODE_STREAM_DATA) hpsb_free_tlabel(packet); - packet->data = NULL; hpsb_free_packet(packet); } @@ -1583,9 +1580,9 @@ { struct sk_buff *skb = ptask->skb; struct net_device *dev = skb->dev; - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; unsigned long flags; - + /* Statistics */ spin_lock_irqsave(&priv->lock, flags); if (fail) { @@ -1616,8 +1613,7 @@ ether1394_free_packet(packet); ptask->outstanding_pkts--; - if (ptask->outstanding_pkts > 0 && !fail) - { + if (ptask->outstanding_pkts > 0 && !fail) { int tx_len; /* Add the encapsulation header to the fragment */ @@ -1637,7 +1633,7 @@ { int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; struct eth1394hdr *eth; - struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; + struct eth1394_priv *priv = dev->priv; int proto; unsigned long flags; nodeid_t dest_node; @@ -1797,7 +1793,7 @@ case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; strcpy (info.driver, driver_name); - strcpy (info.version, "$Rev: 1175 $"); + strcpy (info.version, "$Rev: 1198 $"); /* FIXME XXX provide sane businfo */ strcpy (info.bus_info, "ieee1394"); if (copy_to_user (useraddr, &info, sizeof (info))) diff -Nru a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c --- a/drivers/ieee1394/highlevel.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/highlevel.c Sun Apr 18 13:42:41 2004 @@ -493,7 +493,7 @@ return 0; } -void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, +void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned int channel) { if (channel > 63) { diff -Nru a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h --- a/drivers/ieee1394/highlevel.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/highlevel.h Sun Apr 18 13:42:40 2004 @@ -5,7 +5,7 @@ struct hpsb_address_serve { struct list_head host_list; /* per host list */ - + struct list_head hl_list; /* hpsb_highlevel list */ struct hpsb_address_ops *op; @@ -19,7 +19,7 @@ /* * The above structs are internal to highlevel driver handling. Only the - * following structures are of interest to actual highlevel drivers. + * following structures are of interest to actual highlevel drivers. */ struct hpsb_highlevel { @@ -68,8 +68,8 @@ struct hpsb_address_ops { /* - * Null function pointers will make the respective operation complete - * with RCODE_TYPE_ERROR. Makes for easy to implement read-only + * Null function pointers will make the respective operation complete + * with RCODE_TYPE_ERROR. Makes for easy to implement read-only * registers (just leave everything but read NULL). * * All functions shall return appropriate IEEE 1394 rcodes. @@ -77,7 +77,7 @@ /* These functions have to implement block reads for themselves. */ /* These functions either return a response code - or a negative number. In the first case a response will be generated; in the + or a negative number. In the first case a response will be generated; in the later case, no response will be sent and the driver, that handled the request will send the response itself */ @@ -104,7 +104,7 @@ a packet arrives. The flags argument contains the second word of the first header quadlet of the incoming packet (containing transaction label, retry code, transaction code and priority). These functions either return a response code - or a negative number. In the first case a response will be generated; in the + or a negative number. In the first case a response will be generated; in the later case, no response will be sent and the driver, that handled the request will send the response itself. */ @@ -155,7 +155,7 @@ * Enable or disable receving a certain isochronous channel through the * iso_receive op. */ -int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, +int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned int channel); void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, unsigned int channel); diff -Nru a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c --- a/drivers/ieee1394/hosts.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/hosts.c Sun Apr 18 13:42:40 2004 @@ -126,9 +126,7 @@ h->hostdata = h + 1; h->driver = drv; - INIT_LIST_HEAD(&h->pending_packets); - spin_lock_init(&h->pending_pkt_lock); - + skb_queue_head_init(&h->pending_packet_queue); INIT_LIST_HEAD(&h->addr_space); init_timer(&h->delayed_reset); diff -Nru a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h --- a/drivers/ieee1394/hosts.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/hosts.h Sun Apr 18 13:42:40 2004 @@ -5,6 +5,8 @@ #include #include #include +#include + #include #include "ieee1394_types.h" @@ -21,8 +23,8 @@ atomic_t generation; - struct list_head pending_packets; - spinlock_t pending_pkt_lock; + struct sk_buff_head pending_packet_queue; + struct timer_list timeout; unsigned long timeout_interval; @@ -164,7 +166,7 @@ * called. Return 0 on success, negative errno on failure. * NOTE: The function must be callable in interrupt context. */ - int (*transmit_packet) (struct hpsb_host *host, + int (*transmit_packet) (struct hpsb_host *host, struct hpsb_packet *packet); /* This function requests miscellanous services from the driver, see diff -Nru a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h --- a/drivers/ieee1394/ieee1394.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/ieee1394.h Sun Apr 18 13:42:40 2004 @@ -39,7 +39,7 @@ #define ACK_TARDY 0xb #define ACK_CONFLICT_ERROR 0xc #define ACK_DATA_ERROR 0xd -#define ACK_TYPE_ERROR 0xe +#define ACK_TYPE_ERROR 0xe #define ACK_ADDRESS_ERROR 0xf /* Non-standard "ACK codes" for internal use */ @@ -74,7 +74,7 @@ #define SELFID_PORT_CHILD 0x3 #define SELFID_PORT_PARENT 0x2 #define SELFID_PORT_NCONN 0x1 -#define SELFID_PORT_NONE 0x0 +#define SELFID_PORT_NONE 0x0 #include diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c --- a/drivers/ieee1394/ieee1394_core.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/ieee1394_core.c Sun Apr 18 13:42:40 2004 @@ -31,6 +31,8 @@ #include #include #include +#include + #include #include @@ -56,8 +58,6 @@ /* We are GPL, so treat us special */ MODULE_LICENSE("GPL"); -static kmem_cache_t *hpsb_packet_cache; - /* Some globals used */ const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; @@ -122,30 +122,27 @@ struct hpsb_packet *hpsb_alloc_packet(size_t data_size) { struct hpsb_packet *packet = NULL; - void *data = NULL; - int gfp_flags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; + struct sk_buff *skb; - packet = kmem_cache_alloc(hpsb_packet_cache, gfp_flags); - if (packet == NULL) + data_size = ((data_size + 3) & ~3); + + skb = alloc_skb(data_size + sizeof(*packet), GFP_ATOMIC); + if (skb == NULL) return NULL; - memset(packet, 0, sizeof(*packet)); + memset(skb->data, 0, data_size + sizeof(*packet)); + + packet = (struct hpsb_packet *)skb->data; + packet->skb = skb; packet->header = packet->embedded_header; - INIT_LIST_HEAD(&packet->list); packet->state = hpsb_unused; packet->generation = -1; + INIT_LIST_HEAD(&packet->driver_list); atomic_set(&packet->refcnt, 1); if (data_size) { - data_size = (data_size + 3) & ~3; - data = kmalloc(data_size + 8, gfp_flags); - if (data == NULL) { - kmem_cache_free(hpsb_packet_cache, packet); - return NULL; - } - - packet->data = data; + packet->data = (quadlet_t *)(skb->data + sizeof(*packet)); packet->data_size = data_size; } @@ -162,8 +159,8 @@ void hpsb_free_packet(struct hpsb_packet *packet) { if (packet && atomic_dec_and_test(&packet->refcnt)) { - kfree(packet->data); - kmem_cache_free(hpsb_packet_cache, packet); + BUG_ON(!list_empty(&packet->driver_list)); + kfree_skb(packet->skb); } } @@ -219,13 +216,13 @@ if (!sid->extended) { nodeid++; esid_seq = 0; - + if (sid->phy_id != nodeid) { HPSB_INFO("SelfIDs failed monotony check with " "%d", sid->phy_id); return 0; } - + if (sid->link_active) { host->nodes_active++; if (sid->contender) @@ -234,7 +231,7 @@ } else { esid = (struct ext_selfid *)sid; - if ((esid->phy_id != nodeid) + if ((esid->phy_id != nodeid) || (esid->seq_nr != esid_seq)) { HPSB_INFO("SelfIDs failed monotony check with " "%d/%d", esid->phy_id, esid->seq_nr); @@ -244,24 +241,24 @@ } sid++; } - + esid = (struct ext_selfid *)(sid - 1); while (esid->extended) { if ((esid->porta == 0x2) || (esid->portb == 0x2) || (esid->portc == 0x2) || (esid->portd == 0x2) || (esid->porte == 0x2) || (esid->portf == 0x2) || (esid->portg == 0x2) || (esid->porth == 0x2)) { - HPSB_INFO("SelfIDs failed root check on " - "extended SelfID"); - return 0; + HPSB_INFO("SelfIDs failed root check on " + "extended SelfID"); + return 0; } esid--; } sid = (struct selfid *)esid; if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) { - HPSB_INFO("SelfIDs failed root check"); - return 0; + HPSB_INFO("SelfIDs failed root check"); + return 0; } host->node_count = nodeid + 1; @@ -400,7 +397,7 @@ } -void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, +void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet, int ackcode) { packet->ack_code = ackcode; @@ -413,7 +410,7 @@ if (ackcode != ACK_PENDING || !packet->expect_response) { atomic_dec(&packet->refcnt); - list_del(&packet->list); + skb_unlink(packet->skb); packet->state = hpsb_complete; queue_packet_complete(packet); return; @@ -505,17 +502,17 @@ packet->state = hpsb_queued; - if (!packet->no_waiter || packet->expect_response) { - unsigned long flags; + /* This just seems silly to me */ + WARN_ON(packet->no_waiter && packet->expect_response); + if (!packet->no_waiter || packet->expect_response) { atomic_inc(&packet->refcnt); - spin_lock_irqsave(&host->pending_pkt_lock, flags); - list_add_tail(&packet->list, &host->pending_packets); - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); + skb_queue_tail(&host->pending_packet_queue, packet->skb); } - if (packet->node_id == host->node_id) - { /* it is a local request, so handle it locally */ + if (packet->node_id == host->node_id) { + /* it is a local request, so handle it locally */ + quadlet_t *data; size_t size = packet->data_size + packet->header_size; @@ -547,6 +544,7 @@ + NODEID_TO_NODE(packet->node_id)]; } +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG switch (packet->speed_code) { case 2: dump_packet("send packet 400:", packet->header, @@ -560,6 +558,7 @@ dump_packet("send packet 100:", packet->header, packet->header_size); } +#endif return host->driver->transmit_packet(host, packet); } @@ -595,80 +594,78 @@ } -void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data, - size_t size) +static void handle_packet_response(struct hpsb_host *host, int tcode, + quadlet_t *data, size_t size) { struct hpsb_packet *packet = NULL; - struct list_head *lh; + struct sk_buff *skb; int tcode_match = 0; int tlabel; unsigned long flags; tlabel = (data[0] >> 10) & 0x3f; - spin_lock_irqsave(&host->pending_pkt_lock, flags); + spin_lock_irqsave(&host->pending_packet_queue.lock, flags); - list_for_each(lh, &host->pending_packets) { - packet = list_entry(lh, struct hpsb_packet, list); + skb_queue_walk(&host->pending_packet_queue, skb) { + packet = (struct hpsb_packet *)skb->data; if ((packet->tlabel == tlabel) && (packet->node_id == (data[1] >> 16))){ break; } + + packet = NULL; } - if (lh == &host->pending_packets) { + if (packet == NULL) { HPSB_DEBUG("unsolicited response packet received - no tlabel match"); dump_packet("contents:", data, 16); - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); + spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); return; } switch (packet->tcode) { case TCODE_WRITEQ: case TCODE_WRITEB: - if (tcode == TCODE_WRITE_RESPONSE) tcode_match = 1; + if (tcode != TCODE_WRITE_RESPONSE) + break; + tcode_match = 1; + memcpy(packet->header, data, 12); break; case TCODE_READQ: - if (tcode == TCODE_READQ_RESPONSE) tcode_match = 1; + if (tcode != TCODE_READQ_RESPONSE) + break; + tcode_match = 1; + memcpy(packet->header, data, 16); break; case TCODE_READB: - if (tcode == TCODE_READB_RESPONSE) tcode_match = 1; + if (tcode != TCODE_READB_RESPONSE) + break; + tcode_match = 1; + BUG_ON(packet->skb->len - sizeof(*packet) < size - 16); + memcpy(packet->header, data, 16); + memcpy(packet->data, data + 4, size - 16); break; case TCODE_LOCK_REQUEST: - if (tcode == TCODE_LOCK_RESPONSE) tcode_match = 1; + if (tcode != TCODE_LOCK_RESPONSE) + break; + tcode_match = 1; + size = min((size - 16), (size_t)8); + BUG_ON(packet->skb->len - sizeof(*packet) < size); + memcpy(packet->header, data, 16); + memcpy(packet->data, data + 4, size); break; } - if (!tcode_match || (packet->tlabel != tlabel) - || (packet->node_id != (data[1] >> 16))) { + if (!tcode_match) { HPSB_INFO("unsolicited response packet received - tcode mismatch"); dump_packet("contents:", data, 16); - - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); + spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); return; } - list_del(&packet->list); - - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - - /* FIXME - update size fields? */ - switch (tcode) { - case TCODE_WRITE_RESPONSE: - memcpy(packet->header, data, 12); - break; - case TCODE_READQ_RESPONSE: - memcpy(packet->header, data, 16); - break; - case TCODE_READB_RESPONSE: - memcpy(packet->header, data, 16); - memcpy(packet->data, data + 4, size - 16); - break; - case TCODE_LOCK_RESPONSE: - memcpy(packet->header, data, 16); - memcpy(packet->data, data + 4, (size - 16) > 8 ? 8 : size - 16); - break; - } + __skb_unlink(skb, skb->list); + spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); if (packet->state == hpsb_queued) { packet->sendtime = jiffies; @@ -685,10 +682,8 @@ { struct hpsb_packet *p; - dsize += (dsize % 4 ? 4 - (dsize % 4) : 0); - p = hpsb_alloc_packet(dsize); - if (p == NULL) { + if (unlikely(p == NULL)) { /* FIXME - send data_error response */ return NULL; } @@ -702,9 +697,8 @@ p->generation = get_hpsb_generation(host); - if (dsize % 4) { - p->data[dsize / 4] = 0; - } + if (dsize % 4) + p->data[dsize / 4] = 0; return p; } @@ -851,11 +845,11 @@ fill_async_lock_resp(packet, rcode, extcode, 4); break; case 8: - if ((extcode != EXTCODE_FETCH_ADD) + if ((extcode != EXTCODE_FETCH_ADD) && (extcode != EXTCODE_LITTLE_ADD)) { rcode = highlevel_lock(host, source, packet->data, addr, - data[5], data[4], + data[5], data[4], extcode, flags); fill_async_lock_resp(packet, rcode, extcode, 4); } else { @@ -870,7 +864,7 @@ rcode = highlevel_lock64(host, source, (octlet_t *)packet->data, addr, *(octlet_t *)(data + 6), - *(octlet_t *)(data + 4), + *(octlet_t *)(data + 4), extcode, flags); fill_async_lock_resp(packet, rcode, extcode, 8); break; @@ -932,7 +926,7 @@ break; default: - HPSB_NOTICE("received packet with bogus transaction code %d", + HPSB_NOTICE("received packet with bogus transaction code %d", tcode); break; } @@ -941,74 +935,75 @@ void abort_requests(struct hpsb_host *host) { - unsigned long flags; - struct hpsb_packet *packet, *packet_next; - LIST_HEAD(llist); + struct hpsb_packet *packet; + struct sk_buff *skb; + + host->driver->devctl(host, CANCEL_REQUESTS, 0); - host->driver->devctl(host, CANCEL_REQUESTS, 0); + while ((skb = skb_dequeue(&host->pending_packet_queue)) != NULL) { + packet = (struct hpsb_packet *)skb->data; - spin_lock_irqsave(&host->pending_pkt_lock, flags); - list_splice(&host->pending_packets, &llist); - INIT_LIST_HEAD(&host->pending_packets); - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - - list_for_each_entry_safe(packet, packet_next, &llist, list) { - list_del(&packet->list); - packet->state = hpsb_complete; - packet->ack_code = ACKX_ABORTED; + packet->state = hpsb_complete; + packet->ack_code = ACKX_ABORTED; queue_packet_complete(packet); - } + } } void abort_timedouts(unsigned long __opaque) { struct hpsb_host *host = (struct hpsb_host *)__opaque; - unsigned long flags; - struct hpsb_packet *packet, *packet_next; - unsigned long expire; - LIST_HEAD(expiredlist); + unsigned long flags; + struct hpsb_packet *packet; + struct sk_buff *skb; + unsigned long expire; - spin_lock_irqsave(&host->csr.lock, flags); + spin_lock_irqsave(&host->csr.lock, flags); expire = host->csr.expire; - spin_unlock_irqrestore(&host->csr.lock, flags); - - spin_lock_irqsave(&host->pending_pkt_lock, flags); + spin_unlock_irqrestore(&host->csr.lock, flags); - list_for_each_entry_safe(packet, packet_next, &host->pending_packets, list) { - if (time_before(packet->sendtime + expire, jiffies)) { - list_del(&packet->list); - list_add(&packet->list, &expiredlist); - } - } + /* Hold the lock around this, since we aren't dequeuing all + * packets, just ones we need. */ + spin_lock_irqsave(&host->pending_packet_queue.lock, flags); + + while (!skb_queue_empty(&host->pending_packet_queue)) { + skb = skb_peek(&host->pending_packet_queue); + + packet = (struct hpsb_packet *)skb->data; + + if (time_before(packet->sendtime + expire, jiffies)) { + __skb_unlink(skb, skb->list); + packet->state = hpsb_complete; + packet->ack_code = ACKX_TIMEOUT; + queue_packet_complete(packet); + } else { + /* Since packets are added to the tail, the oldest + * ones are first, always. When we get to one that + * isn't timed out, the rest aren't either. */ + break; + } + } - if (!list_empty(&host->pending_packets)) + if (!skb_queue_empty(&host->pending_packet_queue)) mod_timer(&host->timeout, jiffies + host->timeout_interval); - spin_unlock_irqrestore(&host->pending_pkt_lock, flags); - - list_for_each_entry_safe(packet, packet_next, &expiredlist, list) { - list_del(&packet->list); - packet->state = hpsb_complete; - packet->ack_code = ACKX_TIMEOUT; - queue_packet_complete(packet); - } + spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags); } + +/* Kernel thread and vars, which handles packets that are completed. Only + * packets that have a "complete" function are sent here. This way, the + * completion is run out of kernel context, and doesn't block the rest of + * the stack. */ static int khpsbpkt_pid = -1; static DECLARE_COMPLETION(khpsbpkt_complete); -static LIST_HEAD(hpsbpkt_list); +struct sk_buff_head hpsbpkt_queue; static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); -static spinlock_t khpsbpkt_lock = SPIN_LOCK_UNLOCKED; static void queue_packet_complete(struct hpsb_packet *packet) { if (packet->complete_routine != NULL) { - unsigned long flags; - - spin_lock_irqsave(&khpsbpkt_lock, flags); - list_add_tail(&packet->list, &hpsbpkt_list); - spin_unlock_irqrestore(&khpsbpkt_lock, flags); + skb_queue_tail(&hpsbpkt_queue, packet->skb); /* Signal the kernel thread to handle this */ up(&khpsbpkt_sig); @@ -1018,24 +1013,24 @@ static int hpsbpkt_thread(void *__hi) { - struct hpsb_packet *packet, *next; - unsigned long flags; + struct sk_buff *skb; + struct hpsb_packet *packet; + void (*complete_routine)(void*); + void *complete_data; daemonize("khpsbpkt"); - allow_signal(SIGTERM); while (!down_interruptible(&khpsbpkt_sig)) { - spin_lock_irqsave(&khpsbpkt_lock, flags); - list_for_each_entry_safe(packet, next, &hpsbpkt_list, list) { - void (*complete_routine)(void*) = packet->complete_routine; - void *complete_data = packet->complete_data; + while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { + packet = (struct hpsb_packet *)skb->data; + + complete_routine = packet->complete_routine; + complete_data = packet->complete_data; - list_del(&packet->list); packet->complete_routine = packet->complete_data = NULL; complete_routine(complete_data); } - spin_unlock_irqrestore(&khpsbpkt_lock, flags); } complete_and_exit(&khpsbpkt_complete, 0); @@ -1046,6 +1041,8 @@ { int i; + skb_queue_head_init(&hpsbpkt_queue); + if (hpsb_init_config_roms()) { HPSB_ERR("Failed to initialize some config rom entries.\n"); HPSB_ERR("Some features may not be available\n"); @@ -1066,9 +1063,6 @@ devfs_mk_dir("ieee1394"); - hpsb_packet_cache = kmem_cache_create("hpsb_packet", sizeof(struct hpsb_packet), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - bus_register(&ieee1394_bus_type); for (i = 0; fw_bus_attrs[i]; i++) bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]); @@ -1103,8 +1097,6 @@ kill_proc(khpsbpkt_pid, SIGTERM, 1); wait_for_completion(&khpsbpkt_complete); } - - kmem_cache_destroy(hpsb_packet_cache); hpsb_cleanup_config_roms(); diff -Nru a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h --- a/drivers/ieee1394/ieee1394_core.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/ieee1394_core.h Sun Apr 18 13:42:40 2004 @@ -12,9 +12,13 @@ struct hpsb_packet { /* This struct is basically read-only for hosts with the exception of * the data buffer contents and xnext - see below. */ - struct list_head list; - /* This can be used for host driver internal linking. */ + /* This can be used for host driver internal linking. + * + * NOTE: This must be left in init state when the driver is done + * with it (e.g. by using list_del_init()), since the core does + * some sanity checks to make sure the packet is not on a + * driver_list when free'ing it. */ struct list_head driver_list; nodeid_t node_id; @@ -27,10 +31,9 @@ * queued = queued for sending * pending = sent, waiting for response * complete = processing completed, successful or not - * incoming = incoming packet */ - enum { - hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete, hpsb_incoming + enum { + hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete } __attribute__((packed)) state; /* These are core internal. */ @@ -67,6 +70,9 @@ void (*complete_routine)(void *); void *complete_data; + /* XXX This is just a hack at the moment */ + struct sk_buff *skb; + /* Store jiffies for implementing bus timeouts. */ unsigned long sendtime; @@ -141,7 +147,7 @@ */ void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid); -/* +/* * Notify completion of SelfID stage to the core and report new physical ID * and whether host is root now. */ diff -Nru a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c --- a/drivers/ieee1394/ieee1394_transactions.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/ieee1394_transactions.c Sun Apr 18 13:42:40 2004 @@ -67,7 +67,7 @@ packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0); } -static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, +static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, int length) { PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST); @@ -89,10 +89,10 @@ packet->tcode = TCODE_ISO_DATA; } -static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) -{ +static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) +{ packet->header[0] = data; - packet->header[1] = ~data; + packet->header[1] = ~data; packet->header_size = 8; packet->data_size = 0; packet->expect_response = 0; @@ -145,7 +145,7 @@ } spin_lock_irqsave(&tp->lock, flags); - + packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next); if (packet->tlabel > 63) packet->tlabel = find_first_zero_bit(tp->pool, 64); @@ -158,7 +158,7 @@ return 0; } -/** +/** * hpsb_free_tlabel - free an allocated transaction label * @packet: packet whos tlabel/tpool needs to be cleared * @@ -173,7 +173,7 @@ { unsigned long flags; struct hpsb_tlabel_pool *tp; - + tp = &packet->host->tpool[packet->node_id & NODE_MASK]; BUG_ON(packet->tlabel > 63 || packet->tlabel < 0); @@ -204,7 +204,7 @@ return -EINVAL; default: HPSB_ERR("received reserved rcode %d from node %d", - (packet->header[1] >> 12) & 0xf, + (packet->header[1] >> 12) & 0xf, packet->node_id); return -EAGAIN; } @@ -268,7 +268,7 @@ if (length == 0) return NULL; - packet = hpsb_alloc_packet((length + 3) & ~3); + packet = hpsb_alloc_packet(length); if (!packet) return NULL; @@ -296,7 +296,7 @@ if (length == 0) return NULL; - packet = hpsb_alloc_packet((length + 3) & ~3); + packet = hpsb_alloc_packet(length); if (!packet) return NULL; @@ -330,7 +330,7 @@ if (length == 0) return NULL; - packet = hpsb_alloc_packet((length + 3) & ~3); + packet = hpsb_alloc_packet(length); if (!packet) return NULL; @@ -338,7 +338,7 @@ packet->data[length >> 2] = 0; } packet->host = host; - + if (hpsb_get_tlabel(packet)) { hpsb_free_packet(packet); return NULL; @@ -430,17 +430,17 @@ } struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, - quadlet_t data) + quadlet_t data) { - struct hpsb_packet *p; + struct hpsb_packet *p; - p = hpsb_alloc_packet(0); - if (!p) return NULL; + p = hpsb_alloc_packet(0); + if (!p) return NULL; - p->host = host; - fill_phy_packet(p, data); + p->host = host; + fill_phy_packet(p, data); - return p; + return p; } struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, @@ -470,7 +470,7 @@ { struct hpsb_packet *packet; int retval = 0; - + if (length == 0) return -EINVAL; @@ -544,7 +544,7 @@ BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); + packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); if (!packet) return -ENOMEM; @@ -607,7 +607,7 @@ HPSB_VERBOSE("Send GASP: channel = %d, length = %Zd", channel, length); length += 8; - + packet = hpsb_make_streampacket(host, NULL, length, channel, 3, 0); if (!packet) return -ENOMEM; diff -Nru a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c --- a/drivers/ieee1394/iso.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/iso.c Sun Apr 18 13:42:41 2004 @@ -274,7 +274,7 @@ cycle %= 8000; isoctl_args[0] = cycle; - + if (tag_mask < 0) /* match all tags */ tag_mask = 0xF; @@ -358,7 +358,7 @@ } } -out: +out: spin_unlock_irqrestore(&iso->lock, flags); return rv; } diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c --- a/drivers/ieee1394/nodemgr.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/nodemgr.c Sun Apr 18 13:42:41 2004 @@ -88,7 +88,7 @@ }; -/* +/* * Basically what we do here is start off retrieving the bus_info block. * From there will fill in some info about the node, verify it is of IEEE * 1394 type, and that the crc checks out ok. After that we start off with @@ -102,7 +102,7 @@ * that's easy to parse by the protocol interface. */ -/* +/* * The nodemgr relies heavily on the Driver Model for device callbacks and * driver/device mappings. The old nodemgr used to handle all this itself, * but now we are much simpler because of the LDM. @@ -273,7 +273,7 @@ ne->busopt.irmc, ne->busopt.cmc, ne->busopt.isc, ne->busopt.bmc, ne->busopt.pmc, ne->busopt.generation, ne->busopt.lnkspd, - ne->busopt.max_rec, + ne->busopt.max_rec, ne->busopt.max_rom, ne->busopt.cyc_clk_acc); } @@ -328,7 +328,7 @@ struct unit_directory *ud = container_of(dev, struct unit_directory, device); return sprintf(buf, "%d\n", ud->ignore_driver); -} +} static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver); @@ -356,7 +356,6 @@ { /* No userlevel access needed */ daemonize("kfwrescan"); - allow_signal(SIGTERM); bus_rescan_devices(&ieee1394_bus_type); @@ -726,7 +725,7 @@ ne->busopt.max_rom = (busoptions >> 8) & 0x3; ne->busopt.generation = (busoptions >> 4) & 0xf; ne->busopt.lnkspd = busoptions & 0x7; - + HPSB_VERBOSE("NodeMgr: raw=0x%08x irmc=%d cmc=%d isc=%d bmc=%d pmc=%d " "cyc_clk_acc=%d max_rec=%d max_rom=%d gen=%d lspd=%d", busoptions, ne->busopt.irmc, ne->busopt.cmc, @@ -1012,7 +1011,7 @@ case CSR1212_KV_ID_UNIT: nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL); - break; + break; case CSR1212_KV_ID_DESCRIPTOR: if (last_key_id == CSR1212_KV_ID_VENDOR) { @@ -1056,13 +1055,14 @@ #define PUT_ENVP(fmt,val) \ do { \ + int printed; \ envp[i++] = buffer; \ - length += snprintf(buffer, buffer_size - length, \ + printed = snprintf(buffer, buffer_size - length, \ fmt, val); \ - if ((buffer_size - length <= 0) || (i >= num_envp)) \ + if ((buffer_size - (length+printed) <= 0) || (i >= num_envp)) \ return -ENOMEM; \ - ++length; \ - buffer += length; \ + length += printed+1; \ + buffer += printed+1; \ } while (0) PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id); @@ -1084,7 +1084,7 @@ char *buffer, int buffer_size) { return -ENODEV; -} +} #endif /* CONFIG_HOTPLUG */ @@ -1150,7 +1150,6 @@ ne->generation = generation; } - static void nodemgr_node_scan_one(struct host_info *hi, @@ -1381,8 +1380,9 @@ static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles) { quadlet_t bc; - - if (!host->is_irm) + + /* if irm_id == -1 then there is no IRM on this bus */ + if (!host->is_irm || host->irm_id == (nodeid_t)-1) return 1; host->csr.broadcast_channel |= 0x40000000; /* set validity bit */ @@ -1467,7 +1467,6 @@ /* No userlevel access needed */ daemonize(hi->daemon_name); - allow_signal(SIGTERM); /* Setup our device-model entries */ nodemgr_create_host_dev_files(host); @@ -1611,7 +1610,7 @@ addr, buffer, length); } -int hpsb_node_write(struct node_entry *ne, u64 addr, +int hpsb_node_write(struct node_entry *ne, u64 addr, quadlet_t *buffer, size_t length) { unsigned int generation = ne->generation; @@ -1621,7 +1620,7 @@ addr, buffer, length); } -int hpsb_node_lock(struct node_entry *ne, u64 addr, +int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, quadlet_t *data, quadlet_t arg) { unsigned int generation = ne->generation; diff -Nru a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h --- a/drivers/ieee1394/nodemgr.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/nodemgr.h Sun Apr 18 13:42:41 2004 @@ -169,7 +169,7 @@ /* * This will fill in the given, pre-initialised hpsb_packet with the current * information from the node entry (host, node ID, generation number). It will - * return false if the node owning the GUID is not accessible (and not modify the + * return false if the node owning the GUID is not accessible (and not modify the * hpsb_packet) and return true otherwise. * * Note that packet sending may still fail in hpsb_send_packet if a bus reset @@ -181,9 +181,9 @@ int hpsb_node_read(struct node_entry *ne, u64 addr, quadlet_t *buffer, size_t length); -int hpsb_node_write(struct node_entry *ne, u64 addr, +int hpsb_node_write(struct node_entry *ne, u64 addr, quadlet_t *buffer, size_t length); -int hpsb_node_lock(struct node_entry *ne, u64 addr, +int hpsb_node_lock(struct node_entry *ne, u64 addr, int extcode, quadlet_t *data, quadlet_t arg); diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c --- a/drivers/ieee1394/ohci1394.c Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/ohci1394.c Sun Apr 18 13:42:41 2004 @@ -32,7 +32,7 @@ * Things implemented, but still in test phase: * . Iso Transmit * . Async Stream Packets Transmit (Receive done via Iso interface) - * + * * Things not implemented: * . DMA error recovery * @@ -41,7 +41,7 @@ * added LONG_RESET_ROOT and SHORT_RESET_ROOT for root holdoff --kk */ -/* +/* * Acknowledgments: * * Adam J Richter @@ -162,7 +162,7 @@ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) static char version[] __devinitdata = - "$Rev: 1172 $ Ben Collins "; + "$Rev: 1203 $ Ben Collins "; /* Module Parameters */ static int phys_dma = 1; @@ -185,7 +185,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev); #ifndef __LITTLE_ENDIAN -static unsigned hdr_sizes[] = +static unsigned hdr_sizes[] = { 3, /* TCODE_WRITEQ */ 4, /* TCODE_WRITEB */ @@ -221,7 +221,7 @@ * IEEE-1394 functionality section * ***********************************/ -static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr) +static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr) { int i; unsigned long flags; @@ -243,9 +243,9 @@ if (i >= OHCI_LOOP_COUNT) PRINT (KERN_ERR, "Get PHY Reg timeout [0x%08x/0x%08x/%d]", r, r & 0x80000000, i); - + spin_unlock_irqrestore (&ohci->phy_reg_lock, flags); - + return (r & 0x00ff0000) >> 16; } @@ -303,7 +303,7 @@ else q0 = q[0]; - if ((self_id_count & 0x80000000) || + if ((self_id_count & 0x80000000) || ((self_id_count & 0x00FF0000) != (q0 & 0x00FF0000))) { PRINT(KERN_ERR, "Error in reception of SelfID packets [0x%08x/0x%08x] (count: %d)", @@ -335,7 +335,7 @@ q0 = q[0]; q1 = q[1]; } - + if (q0 == ~q1) { DBGMSG ("SelfID packet 0x%x received", q0); hpsb_selfid_received(host, cpu_to_be32(q0)); @@ -358,7 +358,7 @@ int i; reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset); - + for (i = 0; i < OHCI_LOOP_COUNT; i++) { if (!(reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset)) break; @@ -367,32 +367,6 @@ DBGMSG ("Soft reset finished"); } -static int run_context(struct ti_ohci *ohci, int reg, char *msg) -{ - u32 nodeId; - - /* check that the node id is valid */ - nodeId = reg_read(ohci, OHCI1394_NodeID); - if (!(nodeId&0x80000000)) { - PRINT(KERN_ERR, - "Running dma failed because Node ID is not valid"); - return -1; - } - - /* check that the node number != 63 */ - if ((nodeId&0x3f)==63) { - PRINT(KERN_ERR, - "Running dma failed because Node ID == 63"); - return -1; - } - - /* Run the dma context */ - reg_write(ohci, reg, 0x8000); - - if (msg) PRINT(KERN_DEBUG, "%s", msg); - - return 0; -} /* Generate the dma receive prgs and start the context */ static void initialize_dma_rcv_ctx(struct dma_rcv_ctx *d, int generate_irq) @@ -404,7 +378,7 @@ for (i=0; inum_desc; i++) { u32 c; - + c = DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH; if (generate_irq) c |= DMA_CTL_IRQ; @@ -433,7 +407,7 @@ /* Set bufferFill, isochHeader, multichannel for IR context */ reg_write(ohci, d->ctrlSet, 0xd0000000); - + /* Set the context match register to match on all tags */ reg_write(ohci, d->ctxtMatch, 0xf0000000); @@ -505,7 +479,7 @@ spin_lock_init(&ohci->phy_reg_lock); spin_lock_init(&ohci->event_lock); - + /* Put some defaults to these undefined bus options */ buf = reg_read(ohci, OHCI1394_BusOptions); buf |= 0xE0000000; /* Enable IRMC, CMC and ISC */ @@ -521,7 +495,7 @@ /* Clear link control register */ reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff); - + /* Enable cycle timer and cycle master and set the IRM * contender bit in our self ID packets. */ reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_CycleTimerEnable | @@ -539,10 +513,10 @@ reg_write(ohci, OHCI1394_ConfigROMmap, ohci->csr_config_rom_bus); /* Now get our max packet size */ - ohci->max_packet_size = + ohci->max_packet_size = 1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1); - /* Don't accept phy packets into AR request context */ + /* Don't accept phy packets into AR request context */ reg_write(ohci, OHCI1394_LinkControlClear, 0x00000400); /* Clear the interrupt mask */ @@ -561,15 +535,15 @@ initialize_dma_trm_ctx(&ohci->at_req_context); initialize_dma_trm_ctx(&ohci->at_resp_context); - /* - * Accept AT requests from all nodes. This probably + /* + * Accept AT requests from all nodes. This probably * will have to be controlled from the subsystem * on a per node basis. */ reg_write(ohci,OHCI1394_AsReqFilterHiSet, 0x80000000); /* Specify AT retries */ - reg_write(ohci, OHCI1394_ATRetries, + reg_write(ohci, OHCI1394_ATRetries, OHCI1394_MAX_AT_REQ_RETRIES | (OHCI1394_MAX_AT_RESP_RETRIES<<4) | (OHCI1394_MAX_PHYS_RESP_RETRIES<<8)); @@ -580,8 +554,8 @@ /* Enable interrupts */ reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_unrecoverableError | - OHCI1394_masterIntEnable | - OHCI1394_busReset | + OHCI1394_masterIntEnable | + OHCI1394_busReset | OHCI1394_selfIDComplete | OHCI1394_RSPkt | OHCI1394_RQPkt | @@ -620,13 +594,46 @@ if (status & 0x20) set_phy_reg(ohci, 8, status & ~1); } + + /* Serial EEPROM Sanity check. */ + if ((ohci->max_packet_size < 512) || + (ohci->max_packet_size > 4096)) { + /* Serial EEPROM contents are suspect, set a sane max packet + * size and print the raw contents for bug reports if verbose + * debug is enabled. */ +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG + int i; +#endif + + PRINT(KERN_DEBUG, "Serial EEPROM has suspicious values, " + "attempting to setting max_packet_size to 512 bytes"); + reg_write(ohci, OHCI1394_BusOptions, + (reg_read(ohci, OHCI1394_BusOptions) & 0xf007) | 0x8002); + ohci->max_packet_size = 512; +#ifdef CONFIG_IEEE1394_VERBOSEDEBUG + PRINT(KERN_DEBUG, " EEPROM Present: %d", + (reg_read(ohci, OHCI1394_Version) >> 24) & 0x1); + reg_write(ohci, OHCI1394_GUID_ROM, 0x80000000); + + for (i = 0; + ((i < 1000) && + (reg_read(ohci, OHCI1394_GUID_ROM) & 0x80000000)); i++) + udelay(10); + + for (i = 0; i < 0x20; i++) { + reg_write(ohci, OHCI1394_GUID_ROM, 0x02000000); + PRINT(KERN_DEBUG, " EEPROM %02x: %02x", i, + (reg_read(ohci, OHCI1394_GUID_ROM) >> 16) & 0xff); + } +#endif + } } -/* +/* * Insert a packet in the DMA fifo and generate the DMA prg * FIXME: rewrite the program in order to accept packets crossing * page boundaries. - * check also that a single dma descriptor doesn't cross a + * check also that a single dma descriptor doesn't cross a * page boundary. */ static void insert_packet(struct ti_ohci *ohci, @@ -644,13 +651,13 @@ d->prg_cpu[idx]->begin.branchAddress = 0; if (d->type == DMA_CTX_ASYNC_RESP) { - /* + /* * For response packets, we need to put a timeout value in - * the 16 lower bits of the status... let's try 1 sec timeout - */ + * the 16 lower bits of the status... let's try 1 sec timeout + */ cycleTimer = reg_read(ohci, OHCI1394_IsochronousCycleTimer); d->prg_cpu[idx]->begin.status = cpu_to_le32( - (((((cycleTimer>>25)&0x7)+1)&0x7)<<13) | + (((((cycleTimer>>25)&0x7)+1)&0x7)<<13) | ((cycleTimer&0x01fff000)>>12)); DBGMSG("cycleTimer: %08x timeStamp: %08x", @@ -674,7 +681,7 @@ } else { /* Sending a normal async request or response */ d->prg_cpu[idx]->data[1] = - (packet->header[1] & 0xFFFF) | + (packet->header[1] & 0xFFFF) | (packet->header[0] & 0xFFFF0000); d->prg_cpu[idx]->data[2] = packet->header[2]; d->prg_cpu[idx]->data[3] = packet->header[3]; @@ -694,10 +701,10 @@ } d->prg_cpu[idx]->end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | - DMA_CTL_IRQ | + DMA_CTL_IRQ | DMA_CTL_BRANCH | packet->data_size); - /* + /* * Check that the packet data buffer * does not cross a page boundary. * @@ -706,7 +713,7 @@ * problem. */ #if 0 - if (cross_bound((unsigned long)packet->data, + if (cross_bound((unsigned long)packet->data, packet->data_size)>0) { /* FIXME: do something about it */ PRINT(KERN_ERR, @@ -723,28 +730,28 @@ d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.status = 0; - if (d->branchAddrPtr) + if (d->branchAddrPtr) *(d->branchAddrPtr) = cpu_to_le32(d->prg_bus[idx] | 0x3); d->branchAddrPtr = &(d->prg_cpu[idx]->end.branchAddress); } else { /* quadlet transmit */ if (packet->type == hpsb_raw) - d->prg_cpu[idx]->begin.control = + d->prg_cpu[idx]->begin.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_IMMEDIATE | - DMA_CTL_IRQ | + DMA_CTL_IRQ | DMA_CTL_BRANCH | (packet->header_size + 4)); else d->prg_cpu[idx]->begin.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_IMMEDIATE | - DMA_CTL_IRQ | + DMA_CTL_IRQ | DMA_CTL_BRANCH | packet->header_size); - if (d->branchAddrPtr) + if (d->branchAddrPtr) *(d->branchAddrPtr) = cpu_to_le32(d->prg_bus[idx] | 0x2); d->branchAddrPtr = @@ -756,11 +763,11 @@ (packet->header[0] & 0xFFFF); d->prg_cpu[idx]->data[1] = packet->header[0] & 0xFFFF0000; packet_swab(d->prg_cpu[idx]->data, packet->tcode); - - d->prg_cpu[idx]->begin.control = - cpu_to_le32(DMA_CTL_OUTPUT_MORE | + + d->prg_cpu[idx]->begin.control = + cpu_to_le32(DMA_CTL_OUTPUT_MORE | DMA_CTL_IMMEDIATE | 0x8); - d->prg_cpu[idx]->end.control = + d->prg_cpu[idx]->end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_UPDATE | DMA_CTL_IRQ | @@ -790,7 +797,7 @@ d->prg_cpu[idx]->end.address, d->prg_cpu[idx]->end.branchAddress, d->prg_cpu[idx]->end.status); - if (d->branchAddrPtr) + if (d->branchAddrPtr) *(d->branchAddrPtr) = cpu_to_le32(d->prg_bus[idx] | 0x3); d->branchAddrPtr = &(d->prg_cpu[idx]->end.branchAddress); } @@ -798,7 +805,7 @@ /* queue the packet in the appropriate context queue */ list_add_tail(&packet->driver_list, &d->fifo_list); - d->prg_ind = (d->prg_ind+1)%d->num_desc; + d->prg_ind = (d->prg_ind + 1) % d->num_desc; } /* @@ -806,46 +813,54 @@ * and runs or wakes up the DMA prg if necessary. * * The function MUST be called with the d->lock held. - */ -static int dma_trm_flush(struct ti_ohci *ohci, struct dma_trm_ctx *d) + */ +static void dma_trm_flush(struct ti_ohci *ohci, struct dma_trm_ctx *d) { - struct hpsb_packet *p; - int idx,z; + struct hpsb_packet *packet, *ptmp; + int idx = d->prg_ind; + int z = 0; - if (list_empty(&d->pending_list) || d->free_prgs == 0) - return 0; + /* insert the packets into the dma fifo */ + list_for_each_entry_safe(packet, ptmp, &d->pending_list, driver_list) { + if (!d->free_prgs) + break; - p = driver_packet(d->pending_list.next); - idx = d->prg_ind; - z = (p->data_size) ? 3 : 2; + /* For the first packet only */ + if (!z) + z = (packet->data_size) ? 3 : 2; - /* insert the packets into the dma fifo */ - while (d->free_prgs > 0 && !list_empty(&d->pending_list)) { - struct hpsb_packet *p = driver_packet(d->pending_list.next); - list_del(&p->driver_list); - insert_packet(ohci, d, p); + /* Insert the packet */ + list_del_init(&packet->driver_list); + insert_packet(ohci, d, packet); } - if (d->free_prgs == 0) - DBGMSG("Transmit DMA FIFO ctx=%d is full... waiting", d->ctx); + /* Nothing must have been done, either no free_prgs or no packets */ + if (z == 0) + return; - /* Is the context running ? (should be unless it is + /* Is the context running ? (should be unless it is the first packet to be sent in this context) */ if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) { + u32 nodeId = reg_read(ohci, OHCI1394_NodeID); + DBGMSG("Starting transmit DMA ctx=%d",d->ctx); - reg_write(ohci, d->cmdPtr, d->prg_bus[idx]|z); - run_context(ohci, d->ctrlSet, NULL); - } - else { + reg_write(ohci, d->cmdPtr, d->prg_bus[idx] | z); + + /* Check that the node id is valid, and not 63 */ + if (!(nodeId & 0x80000000) || (nodeId & 0x3f) == 63) + PRINT(KERN_ERR, "Running dma failed because Node ID is not valid"); + else + reg_write(ohci, d->ctrlSet, 0x8000); + } else { /* Wake up the dma context if necessary */ - if (!(reg_read(ohci, d->ctrlSet) & 0x400)) { + if (!(reg_read(ohci, d->ctrlSet) & 0x400)) DBGMSG("Waking transmit DMA ctx=%d",d->ctx); - } /* do this always, to avoid race condition */ reg_write(ohci, d->ctrlSet, 0x1000); } - return 1; + + return; } /* Transmission of an async or iso packet */ @@ -871,7 +886,7 @@ * interrupt context, so we bail out if that is the * case. I don't see anyone sending ISO packets from * interrupt context anyway... */ - + if (ohci->it_legacy_context.ohci == NULL) { if (in_interrupt()) { PRINT(KERN_ERR, @@ -889,11 +904,11 @@ initialize_dma_trm_ctx(&ohci->it_legacy_context); } - + d = &ohci->it_legacy_context; } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) d = &ohci->at_resp_context; - else + else d = &ohci->at_req_context; spin_lock_irqsave(&d->lock,flags); @@ -986,7 +1001,7 @@ * enable cycleTimer, cycleMaster */ DBGMSG("Cycle master enabled"); - reg_write(ohci, OHCI1394_LinkControlSet, + reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_CycleTimerEnable | OHCI1394_LinkControl_CycleMaster); } @@ -1011,7 +1026,7 @@ if (arg<0 || arg>63) { PRINT(KERN_ERR, - "%s: IS0 listen channel %d is out of range", + "%s: IS0 listen channel %d is out of range", __FUNCTION__, arg); return -EFAULT; } @@ -1038,7 +1053,7 @@ if (ohci->ISO_channel_usage & mask) { PRINT(KERN_ERR, - "%s: IS0 listen channel %d is already used", + "%s: IS0 listen channel %d is already used", __FUNCTION__, arg); spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); return -EFAULT; @@ -1047,12 +1062,12 @@ ohci->ISO_channel_usage |= mask; ohci->ir_legacy_channels |= mask; - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, - 1<<(arg-32)); + if (arg>31) + reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, + 1<<(arg-32)); else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet, - 1<IR_channel_lock, flags); DBGMSG("Listening enabled on channel %d", arg); @@ -1064,32 +1079,32 @@ if (arg<0 || arg>63) { PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is out of range", + "%s: IS0 unlisten channel %d is out of range", __FUNCTION__, arg); return -EFAULT; } mask = (u64)0x1<IR_channel_lock, flags); if (!(ohci->ISO_channel_usage & mask)) { PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is not used", + "%s: IS0 unlisten channel %d is not used", __FUNCTION__, arg); spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); return -EFAULT; } - + ohci->ISO_channel_usage &= ~mask; ohci->ir_legacy_channels &= ~mask; - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, - 1<<(arg-32)); + if (arg>31) + reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, + 1<<(arg-32)); else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, - 1<IR_channel_lock, flags); DBGMSG("Listening disabled on channel %d", arg); @@ -1215,7 +1230,7 @@ /* iso->irq_interval is in packets - translate that to blocks */ if (iso->irq_interval == 1) - recv->block_irq_interval = 1; + recv->block_irq_interval = 1; else recv->block_irq_interval = iso->irq_interval * ((recv->nblocks+1)/iso->buf_packets); @@ -1241,7 +1256,7 @@ for (recv->buf_stride = 8; recv->buf_stride < max_packet_size; recv->buf_stride *= 2); - + if (recv->buf_stride*iso->buf_packets > iso->buf_size || recv->buf_stride > PAGE_SIZE) { /* this shouldn't happen, but anyway... */ @@ -1285,7 +1300,7 @@ reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, 0xFFFFFFFF); reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, 0xFFFFFFFF); } - + /* write the DMA program */ ohci_iso_recv_program(iso); @@ -1293,7 +1308,7 @@ " (%u bytes), using %u blocks, buf_stride %u, block_irq_interval %d", recv->dma_mode == BUFFER_FILL_MODE ? "buffer-fill" : "packet-per-buffer", - iso->buf_size/PAGE_SIZE, iso->buf_size, + iso->buf_size/PAGE_SIZE, iso->buf_size, recv->nblocks, recv->buf_stride, recv->block_irq_interval); return 0; @@ -1309,7 +1324,7 @@ /* disable interrupts */ reg_write(recv->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << recv->task.context); - + /* halt DMA */ ohci1394_stop_context(recv->ohci, recv->ContextControlClear, NULL); } @@ -1457,20 +1472,20 @@ if (cycle != -1) { u32 seconds; - + /* enable cycleMatch */ reg_write(recv->ohci, recv->ContextControlSet, (1 << 29)); /* set starting cycle */ cycle &= 0x1FFF; - + /* 'cycle' is only mod 8000, but we also need two 'seconds' bits - just snarf them from the current time */ seconds = reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer) >> 25; /* advance one second to give some extra time for DMA to start */ seconds += 1; - + cycle |= (seconds & 3) << 13; contextMatch |= cycle << 12; @@ -1535,7 +1550,7 @@ next->control |= cpu_to_le32(3 << 20); next->status = cpu_to_le32(recv->buf_stride); - /* link prev to next */ + /* link prev to next */ prev->branchAddress = cpu_to_le32(dma_prog_region_offset_to_bus(&recv->prog, sizeof(struct dma_cmd) * next_i) | 1); /* Z=1 */ @@ -1593,15 +1608,15 @@ int wake = 0; int runaway = 0; struct ti_ohci *ohci = recv->ohci; - + while (1) { /* we expect the next parsable packet to begin at recv->dma_offset */ /* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */ - + unsigned int offset; unsigned short len, cycle; unsigned char channel, tag, sy; - + unsigned char *p = iso->data_buf.kvirt; unsigned int this_block = recv->dma_offset/recv->buf_stride; @@ -1619,26 +1634,26 @@ break; wake = 1; - + /* parse data length, tag, channel, and sy */ - + /* note: we keep our own local copies of 'len' and 'offset' so the user can't mess with them by poking in the mmap area */ - + len = p[recv->dma_offset+2] | (p[recv->dma_offset+3] << 8); if (len > 4096) { PRINT(KERN_ERR, "IR DMA error - bogus 'len' value %u\n", len); } - + channel = p[recv->dma_offset+1] & 0x3F; tag = p[recv->dma_offset+1] >> 6; sy = p[recv->dma_offset+0] & 0xF; /* advance to data payload */ recv->dma_offset += 4; - + /* check for wrap-around */ if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { recv->dma_offset -= recv->buf_stride*recv->nblocks; @@ -1651,7 +1666,7 @@ recv->dma_offset += len; /* payload is padded to 4 bytes */ - if (len % 4) { + if (len % 4) { recv->dma_offset += 4 - (len%4); } @@ -1700,13 +1715,13 @@ /* loop over all blocks */ for (loop = 0; loop < recv->nblocks; loop++) { - + /* check block_dma to see if it's done */ struct dma_cmd *im = &recv->block[recv->block_dma]; - + /* check the DMA descriptor for new writes to xferStatus */ u16 xferstatus = le32_to_cpu(im->status) >> 16; - + /* rescount is the number of bytes *remaining to be written* in the block */ u16 rescount = le32_to_cpu(im->status) & 0xFFFF; @@ -1728,12 +1743,12 @@ we can't touch it until it's done */ break; } - + /* OK, the block is finished... */ - + /* sync our view of the block */ dma_region_sync_for_cpu(&iso->data_buf, recv->block_dma*recv->buf_stride, recv->buf_stride); - + /* reset the DMA descriptor */ im->status = recv->buf_stride; @@ -1756,11 +1771,11 @@ int count; int wake = 0; struct ti_ohci *ohci = recv->ohci; - + /* loop over the entire buffer */ for (count = 0; count < recv->nblocks; count++) { u32 packet_len = 0; - + /* pointer to the DMA descriptor */ struct dma_cmd *il = ((struct dma_cmd*) recv->prog.kvirt) + iso->pkt_dma; @@ -1774,10 +1789,10 @@ /* this packet hasn't come in yet; we are done for now */ goto out; } - + if (event == 0x11) { /* packet received successfully! */ - + /* rescount is the number of bytes *remaining* in the packet buffer, after the packet was written */ packet_len = recv->buf_stride - rescount; @@ -1790,7 +1805,7 @@ /* sync our view of the buffer */ dma_region_sync_for_cpu(&iso->data_buf, iso->pkt_dma * recv->buf_stride, recv->buf_stride); - + /* record the per-packet info */ { /* iso header is 8 bytes ahead of the data payload */ @@ -1806,7 +1821,7 @@ /* skip iso header */ offset += 8; packet_len -= 8; - + cycle = (hdr[0] | (hdr[1] << 8)) & 0x1FFF; channel = hdr[5] & 0x3F; tag = hdr[5] >> 6; @@ -1814,7 +1829,7 @@ hpsb_iso_packet_received(iso, offset, packet_len, cycle, channel, tag, sy); } - + /* reset the DMA descriptor */ il->status = recv->buf_stride; @@ -1958,7 +1973,7 @@ /* DMA descriptor */ struct iso_xmit_cmd *cmd = dma_region_i(&xmit->prog, struct iso_xmit_cmd, iso->pkt_dma); - + /* check for new writes to xferStatus */ u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16; u8 event = xferstatus & 0x1F; @@ -1971,16 +1986,16 @@ if (event != 0x11) PRINT(KERN_ERR, "IT DMA error - OHCI error code 0x%02x\n", event); - + /* at least one packet went out, so wake up the writer */ wake = 1; - + /* parse cycle */ cycle = le32_to_cpu(cmd->output_last.status) & 0x1FFF; /* tell the subsystem the packet has gone out */ hpsb_iso_packet_sent(iso, cycle, event != 0x11); - + /* reset the DMA descriptor for next time */ cmd->output_last.status = 0; } @@ -2101,14 +2116,14 @@ /* cycle match */ if (cycle != -1) { u32 start = cycle & 0x1FFF; - + /* 'cycle' is only mod 8000, but we also need two 'seconds' bits - just snarf them from the current time */ u32 seconds = reg_read(xmit->ohci, OHCI1394_IsochronousCycleTimer) >> 25; /* advance one second to give some extra time for DMA to start */ seconds += 1; - + start |= (seconds & 3) << 13; reg_write(xmit->ohci, xmit->ContextControlSet, 0x80000000 | (start << 16)); @@ -2201,6 +2216,7 @@ unsigned long flags; LIST_HEAD(packet_list); struct ti_ohci *ohci = d->ohci; + struct hpsb_packet *packet, *ptmp; ohci1394_stop_context(ohci, d->ctrlClear, NULL); @@ -2221,19 +2237,20 @@ spin_unlock_irqrestore(&d->lock, flags); - /* Now process subsystem callbacks for the packets from the - * context. */ + if (list_empty(&packet_list)) + return; - while (!list_empty(&packet_list)) { - struct hpsb_packet *p = driver_packet(packet_list.next); - PRINT(KERN_INFO, - "AT dma reset ctx=%d, aborting transmission", d->ctx); - list_del(&p->driver_list); - hpsb_packet_sent(ohci->host, p, ACKX_ABORTED); + PRINT(KERN_INFO, "AT dma reset ctx=%d, aborting transmission", d->ctx); + + /* Now process subsystem callbacks for the packets from this + * context. */ + list_for_each_entry_safe(packet, ptmp, &packet_list, driver_list) { + list_del_init(&packet->driver_list); + hpsb_packet_sent(ohci->host, packet, ACKX_ABORTED); } } -static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci, +static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci, quadlet_t rx_event, quadlet_t tx_event) { @@ -2393,7 +2410,8 @@ ohci1394_stop_context(ohci, d->ctrlClear, "reqTxComplete"); else - tasklet_schedule(&d->task); + dma_trm_tasklet((unsigned long)d); + //tasklet_schedule(&d->task); event &= ~OHCI1394_reqTxComplete; } if (event & OHCI1394_respTxComplete) { @@ -2436,7 +2454,7 @@ event &= ~OHCI1394_isochRx; } if (event & OHCI1394_isochTx) { - quadlet_t tx_event; + quadlet_t tx_event; tx_event = reg_read(ohci, OHCI1394_IsoXmitIntEventSet); reg_write(ohci, OHCI1394_IsoXmitIntEventClear, tx_event); @@ -2459,7 +2477,7 @@ isroot = (node_id & 0x40000000) != 0; DBGMSG("SelfID interrupt received " - "(phyid %d, %s)", phyid, + "(phyid %d, %s)", phyid, (isroot ? "root" : "not root")); handle_selfid(ohci, host, phyid, isroot); @@ -2535,10 +2553,10 @@ #define cond_le32_to_cpu(data, noswap) \ (noswap ? data : le32_to_cpu(data)) -static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0, +static const int TCODE_SIZE[16] = {20, 0, 16, -1, 16, 20, 20, 0, -1, 0, -1, 0, -1, -1, 16, -1}; -/* +/* * Determine the length of a packet in the buffer * Optimization suggested by Pascal Drolet */ @@ -2669,7 +2687,7 @@ offset=0; } } - + /* We get one phy packet to the async descriptor for each * bus reset. We always ignore it. */ if (tcode != OHCI1394_TCODE_PHY) { @@ -2687,7 +2705,7 @@ ack = (((cond_le32_to_cpu(d->spb[length/4-1], ohci->no_swap_incoming)>>16)&0x1f) == 0x11) ? 1 : 0; - hpsb_packet_received(ohci->host, d->spb, + hpsb_packet_received(ohci->host, d->spb, length-4, ack); } #ifdef OHCI1394_DEBUG @@ -2713,24 +2731,23 @@ { struct dma_trm_ctx *d = (struct dma_trm_ctx*)data; struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci); - struct hpsb_packet *packet; + struct hpsb_packet *packet, *ptmp; unsigned long flags; u32 status, ack; size_t datasize; spin_lock_irqsave(&d->lock, flags); - while (!list_empty(&d->fifo_list)) { - packet = driver_packet(d->fifo_list.next); + list_for_each_entry_safe(packet, ptmp, &d->fifo_list, driver_list) { datasize = packet->data_size; if (datasize && packet->type != hpsb_raw) status = le32_to_cpu( d->prg_cpu[d->sent_ind]->end.status) >> 16; - else + else status = le32_to_cpu( d->prg_cpu[d->sent_ind]->begin.status) >> 16; - if (status == 0) + if (status == 0) /* this packet hasn't been sent yet*/ break; @@ -2738,34 +2755,34 @@ if (datasize) if (((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa) DBGMSG("Stream packet sent to channel %d tcode=0x%X " - "ack=0x%X spd=%d dataLength=%d ctx=%d", + "ack=0x%X spd=%d dataLength=%d ctx=%d", (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>8)&0x3f, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf, - status&0x1f, (status>>5)&0x3, + status&0x1f, (status>>5)&0x3, le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16, d->ctx); else DBGMSG("Packet sent to node %d tcode=0x%X tLabel=" - "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", + "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d", (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1])>>16)&0x3f, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>10)&0x3f, status&0x1f, (status>>5)&0x3, le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3])>>16, d->ctx); - else + else DBGMSG("Packet sent to node %d tcode=0x%X tLabel=" - "0x%02X ack=0x%X spd=%d data=0x%08X ctx=%d", + "0x%02X ack=0x%X spd=%d data=0x%08X ctx=%d", (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[1]) >>16)&0x3f, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) >>4)&0xf, (le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0]) >>10)&0x3f, - status&0x1f, (status>>5)&0x3, + status&0x1f, (status>>5)&0x3, le32_to_cpu(d->prg_cpu[d->sent_ind]->data[3]), d->ctx); -#endif +#endif if (status & 0x10) { ack = status & 0xf; @@ -2818,11 +2835,11 @@ } } - list_del(&packet->driver_list); + list_del_init(&packet->driver_list); hpsb_packet_sent(ohci->host, packet, ack); if (datasize) { - pci_unmap_single(ohci->dev, + pci_unmap_single(ohci->dev, cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), datasize, PCI_DMA_TODEVICE); OHCI_DMA_FREE("single Xmit data packet"); @@ -2867,7 +2884,7 @@ for (i=0; inum_desc; i++) if (d->buf_cpu[i] && d->buf_bus[i]) { pci_free_consistent( - ohci->dev, d->buf_size, + ohci->dev, d->buf_size, d->buf_cpu[i], d->buf_bus[i]); OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i); } @@ -2875,7 +2892,7 @@ kfree(d->buf_bus); } if (d->prg_cpu) { - for (i=0; inum_desc; i++) + for (i=0; inum_desc; i++) if (d->prg_cpu[i] && d->prg_bus[i]) { pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i); @@ -2921,7 +2938,7 @@ memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*)); memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t)); - d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*), + d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*), GFP_KERNEL); d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL); @@ -2946,11 +2963,11 @@ OHCI_DMA_ALLOC("dma_rcv prg pool"); for (i=0; inum_desc; i++) { - d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, + d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, d->buf_size, d->buf_bus+i); OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i); - + if (d->buf_cpu[i] != NULL) { memset(d->buf_cpu[i], 0, d->buf_size); } else { @@ -3015,7 +3032,7 @@ DBGMSG("Freeing dma_trm_ctx %d", d->ctx); if (d->prg_cpu) { - for (i=0; inum_desc; i++) + for (i=0; inum_desc; i++) if (d->prg_cpu[i] && d->prg_bus[i]) { pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); OHCI_DMA_FREE("pool dma_trm prg[%d]", i); @@ -3045,7 +3062,7 @@ d->ctrlClear = 0; d->cmdPtr = 0; - d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*), + d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*), GFP_KERNEL); d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL); @@ -3194,7 +3211,7 @@ * noByteSwapData registers to see if they were not cleared to * zero. Should this work? Obviously it's not defined what these * registers will read when they aren't supported. Bleh! */ - if (dev->vendor == PCI_VENDOR_ID_APPLE && + if (dev->vendor == PCI_VENDOR_ID_APPLE && dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) { ohci->no_swap_incoming = 1; ohci->selfid_swap = 0; @@ -3217,7 +3234,7 @@ /* We hardwire the MMIO length, since some CardBus adaptors * fail to report the right length. Anyway, the ohci spec - * clearly says it's 2kb, so this shouldn't be a problem. */ + * clearly says it's 2kb, so this shouldn't be a problem. */ ohci_base = pci_resource_start(dev, 0); if (pci_resource_len(dev, 0) != OHCI1394_REGISTER_SIZE) PRINT(KERN_WARNING, "Unexpected PCI resource length of %lx!", @@ -3248,7 +3265,7 @@ ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; /* self-id dma buffer allocation */ - ohci->selfid_buf_cpu = + ohci->selfid_buf_cpu = pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, &ohci->selfid_buf_bus); OHCI_DMA_ALLOC("consistent selfid_buf"); @@ -3259,8 +3276,8 @@ if ((unsigned long)ohci->selfid_buf_cpu & 0x1fff) PRINT(KERN_INFO, "SelfID buffer %p is not aligned on " - "8Kb boundary... may cause problems on some CXD3222 chip", - ohci->selfid_buf_cpu); + "8Kb boundary... may cause problems on some CXD3222 chip", + ohci->selfid_buf_cpu); /* No self-id errors at startup */ ohci->self_id_errors = 0; @@ -3423,7 +3440,7 @@ free_dma_trm_ctx(&ohci->it_legacy_context); case OHCI_INIT_HAVE_SELFID_BUFFER: - pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, + pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, ohci->selfid_buf_cpu, ohci->selfid_buf_bus); OHCI_DMA_FREE("consistent selfid_buf"); @@ -3544,7 +3561,7 @@ /* stop the channel program if it's still running */ reg_write(ohci, reg, 0x8000); - + /* Wait until it effectively stops */ while (reg_read(ohci, reg) & 0x400) { i++; diff -Nru a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h --- a/drivers/ieee1394/ohci1394.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/ohci1394.h Sun Apr 18 13:42:40 2004 @@ -110,7 +110,7 @@ int ctxtMatch; }; -/* DMA transmit context */ +/* DMA transmit context */ struct dma_trm_ctx { struct ti_ohci *ohci; enum context_type type; @@ -151,7 +151,7 @@ struct ti_ohci { struct pci_dev *dev; - enum { + enum { OHCI_INIT_ALLOC_HOST, OHCI_INIT_HAVE_MEM_REGION, OHCI_INIT_HAVE_IOMAPPING, @@ -161,17 +161,17 @@ OHCI_INIT_HAVE_IRQ, OHCI_INIT_DONE, } init_state; - + /* remapped memory spaces */ - void *registers; + void *registers; /* dma buffer for self-id packets */ quadlet_t *selfid_buf_cpu; dma_addr_t selfid_buf_bus; /* buffer for csr config rom */ - quadlet_t *csr_config_rom_cpu; - dma_addr_t csr_config_rom_bus; + quadlet_t *csr_config_rom_cpu; + dma_addr_t csr_config_rom_bus; int csr_config_rom_length; unsigned int max_packet_size; @@ -198,7 +198,7 @@ struct dma_rcv_ctx ir_legacy_context; struct ohci1394_iso_tasklet ir_legacy_tasklet; - + /* iso transmit */ int nb_iso_xmit_ctx; unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ @@ -260,7 +260,7 @@ /* 2 KiloBytes of register space */ -#define OHCI1394_REGISTER_SIZE 0x800 +#define OHCI1394_REGISTER_SIZE 0x800 /* Offsets relative to context bases defined below */ @@ -440,9 +440,9 @@ #define OHCI1394_TCODE_PHY 0xE -void ohci1394_init_iso_tasklet(struct ohci1394_iso_tasklet *tasklet, +void ohci1394_init_iso_tasklet(struct ohci1394_iso_tasklet *tasklet, int type, - void (*func)(unsigned long), + void (*func)(unsigned long), unsigned long data); int ohci1394_register_iso_tasklet(struct ti_ohci *ohci, struct ohci1394_iso_tasklet *tasklet); diff -Nru a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c --- a/drivers/ieee1394/pcilynx.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/pcilynx.c Sun Apr 18 13:42:40 2004 @@ -23,7 +23,7 @@ * Contributions: * * Manfred Weihs - * reading bus info block (containing GUID) from serial + * reading bus info block (containing GUID) from serial * eeprom via i2c and storing it in config ROM * Reworked code for initiating bus resets * (long, short, with or without hold-off) @@ -139,7 +139,7 @@ .udelay = 5, .mdelay = 5, .timeout = 100, -}; +}; static struct i2c_adapter bit_ops = { .id = 0xAA, //FIXME: probably we should get an id in i2c-id.h @@ -195,19 +195,19 @@ if (lynx->pcl_bmap[off] & 1<pcl_bmap[off] &= ~(1<id, + PRINT(KERN_ERR, lynx->id, "attempted to free unallocated PCL %d", pclid); } spin_unlock(&lynx->lock); } -/* functions useful for debugging */ +/* functions useful for debugging */ static void pretty_print_pcl(const struct ti_pcl *pcl) { int i; printk("PCL next %08x, userdata %08x, status %08x, remtrans %08x, nextbuf %08x\n", - pcl->next, pcl->user_data, pcl->pcl_status, + pcl->next, pcl->user_data, pcl->pcl_status, pcl->remaining_transfer_count, pcl->next_data_buffer); printk("PCL"); @@ -218,7 +218,7 @@ } printk("\n"); } - + static void print_pcl(const struct ti_lynx *lynx, pcl_t pclid) { struct ti_pcl pcl; @@ -419,7 +419,7 @@ cpu_to_be32s(&q[i]); i--; } - + if (!lynx->phyic.reg_1394a) { lsid = generate_own_selfid(lynx, host); } @@ -437,7 +437,7 @@ while (size > 0) { struct selfid *sid = (struct selfid *)q; - if (!lynx->phyic.reg_1394a && !sid->extended + if (!lynx->phyic.reg_1394a && !sid->extended && (sid->phy_id == (phyid + 1))) { hpsb_selfid_received(host, lsid); } @@ -484,8 +484,7 @@ } packet = driver_packet(d->queue.next); - list_del(&packet->driver_list); - list_add_tail(&packet->driver_list, &d->pcl_queue); + list_move_tail(&packet->driver_list, &d->pcl_queue); d->header_dma = pci_map_single(lynx->dev, packet->header, packet->header_size, PCI_DMA_TODEVICE); @@ -500,11 +499,9 @@ pcl.next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID; pcl.pcl_status = 0; -#ifdef __BIG_ENDIAN pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size; -#else - pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size - | PCL_BIGENDIAN; +#ifdef __BIG_ENDIAN + pcl.buffer[0].control |= PCL_BIGENDIAN; #endif pcl.buffer[0].pointer = d->header_dma; pcl.buffer[1].control = PCL_LAST_BUFF | packet->data_size; @@ -520,7 +517,7 @@ case hpsb_raw: pcl.buffer[0].control |= PCL_CMD_UNFXMT; break; - } + } put_pcl(lynx, d->pcl, &pcl); run_pcl(lynx, d->pcl_start, d->channel); @@ -727,16 +724,16 @@ case GET_CYCLE_COUNTER: retval = reg_read(lynx, CYCLE_TIMER); break; - + case SET_CYCLE_COUNTER: reg_write(lynx, CYCLE_TIMER, arg); break; case SET_BUS_ID: - reg_write(lynx, LINK_ID, + reg_write(lynx, LINK_ID, (arg << 22) | (reg_read(lynx, LINK_ID) & 0x003f0000)); break; - + case ACT_CYCLE_MASTER: if (arg) { reg_set_bits(lynx, LINK_CONTROL, @@ -767,7 +764,7 @@ get_pcl(lynx, lynx->async.pcl, &pcl); packet = driver_packet(lynx->async.pcl_queue.next); - list_del(&packet->driver_list); + list_del_init(&packet->driver_list); pci_unmap_single(lynx->dev, lynx->async.header_dma, packet->header_size, PCI_DMA_TODEVICE); @@ -795,7 +792,7 @@ while (!list_empty(&packet_list)) { packet = driver_packet(packet_list.next); - list_del(&packet->driver_list); + list_del_init(&packet->driver_list); hpsb_packet_sent(host, packet, ACKX_ABORTED); } @@ -803,7 +800,7 @@ case ISO_LISTEN_CHANNEL: spin_lock_irqsave(&lynx->iso_rcv.lock, flags); - + if (lynx->iso_rcv.chan_count++ == 0) { reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ISO_RCV), DMA_WORD1_CMP_ENABLE_MASTER); @@ -875,7 +872,7 @@ int cid = iminor(inode); enum { t_rom, t_aux, t_ram } type; struct memdata *md; - + if (cid < PCILYNX_MINOR_AUX_START) { /* just for completeness */ return -ENXIO; @@ -976,10 +973,10 @@ return newoffs; } -/* - * do not DMA if count is too small because this will have a serious impact +/* + * do not DMA if count is too small because this will have a serious impact * on performance - the value 2400 was found by experiment and may not work - * everywhere as good as here - use mem_mindma option for modules to change + * everywhere as good as here - use mem_mindma option for modules to change */ static short mem_mindma = 2400; module_param(mem_mindma, short, 0444); @@ -1123,7 +1120,7 @@ } -static ssize_t mem_write(struct file *file, const char *buffer, size_t count, +static ssize_t mem_write(struct file *file, const char *buffer, size_t count, loff_t *offset) { struct memdata *md = (struct memdata *)file->private_data; @@ -1292,7 +1289,7 @@ get_pcl(lynx, lynx->async.pcl, &pcl); packet = driver_packet(lynx->async.pcl_queue.next); - list_del(&packet->driver_list); + list_del_init(&packet->driver_list); pci_unmap_single(lynx->dev, lynx->async.header_dma, packet->header_size, PCI_DMA_TODEVICE); @@ -1338,7 +1335,7 @@ get_pcl(lynx, lynx->iso_send.pcl, &pcl); packet = driver_packet(lynx->iso_send.pcl_queue.next); - list_del(&packet->driver_list); + list_del_init(&packet->driver_list); pci_unmap_single(lynx->dev, lynx->iso_send.header_dma, packet->header_size, PCI_DMA_TODEVICE); @@ -1375,7 +1372,7 @@ int stat = reg_read(lynx, DMA_CHAN_STAT(CHANNEL_ASYNC_RCV)); PRINTD(KERN_DEBUG, lynx->id, "received packet size %d", - stat & 0x1fff); + stat & 0x1fff); if (stat & DMA_CHAN_STAT_SELFID) { lynx->selfid_size = stat & 0x1fff; @@ -1417,7 +1414,7 @@ lynx->iso_rcv.stat[idx]); } - if (lynx->iso_rcv.stat[idx] + if (lynx->iso_rcv.stat[idx] & (DMA_CHAN_STAT_PCIERR | DMA_CHAN_STAT_PKTERR)) { PRINT(KERN_INFO, lynx->id, "iso receive error on %d to 0x%p", idx, data); @@ -1460,7 +1457,7 @@ reg_write(lynx, PCI_INT_ENABLE, 0); free_irq(lynx->dev->irq, lynx); - /* Disable IRM Contender */ + /* Disable IRM Contender and LCtrl */ if (lynx->phyic.reg_1394a) set_phy_reg(lynx, 4, ~0xc0 & get_phy_reg(lynx, 4)); @@ -1558,7 +1555,7 @@ if (lynx->pcl_mem != NULL) { lynx->state = have_pcl_mem; - PRINT(KERN_INFO, lynx->id, + PRINT(KERN_INFO, lynx->id, "allocated PCL memory %d Bytes @ 0x%p", LOCALRAM_SIZE, lynx->pcl_mem); } else { @@ -1668,7 +1665,7 @@ lynx->async.channel = CHANNEL_ASYNC_SEND; lynx->iso_send.queue_lock = SPIN_LOCK_UNLOCKED; lynx->iso_send.channel = CHANNEL_ISO_SEND; - + PRINT(KERN_INFO, lynx->id, "remapped memory spaces reg 0x%p, rom 0x%p, " "ram 0x%p, aux 0x%p", lynx->registers, lynx->local_rom, lynx->local_ram, lynx->aux_port); @@ -1698,17 +1695,17 @@ pcl.next = PCL_NEXT_INVALID; pcl.async_error_next = PCL_NEXT_INVALID; -#ifdef __BIG_ENDIAN + pcl.buffer[0].control = PCL_CMD_RCV | 16; - pcl.buffer[1].control = PCL_LAST_BUFF | 4080; -#else - pcl.buffer[0].control = PCL_CMD_RCV | PCL_BIGENDIAN | 16; - pcl.buffer[1].control = PCL_LAST_BUFF | 4080; +#ifdef __BIG_ENDIAN + pcl.buffer[0].control |= PCL_BIGENDIAN; #endif + pcl.buffer[1].control = PCL_LAST_BUFF | 4080; + pcl.buffer[0].pointer = lynx->rcv_page_dma; pcl.buffer[1].pointer = lynx->rcv_page_dma + 16; put_pcl(lynx, lynx->rcv_pcl, &pcl); - + pcl.next = pcl_bus(lynx, lynx->async.pcl); pcl.async_error_next = pcl_bus(lynx, lynx->async.pcl); put_pcl(lynx, lynx->async.pcl_start, &pcl); @@ -1729,7 +1726,7 @@ int page = i / ISORCV_PER_PAGE; int sec = i % ISORCV_PER_PAGE; - pcl.buffer[0].pointer = lynx->iso_rcv.page_dma[page] + pcl.buffer[0].pointer = lynx->iso_rcv.page_dma[page] + sec * MAX_ISORCV_SIZE; pcl.buffer[1].pointer = pcl.buffer[0].pointer + 4; put_pcl(lynx, lynx->iso_rcv.pcl[i], &pcl); @@ -1755,11 +1752,11 @@ reg_write(lynx, LINK_INT_ENABLE, LINK_INT_PHY_TIMEOUT | LINK_INT_PHY_REG_RCVD | LINK_INT_PHY_BUSRESET - | LINK_INT_ISO_STUCK | LINK_INT_ASYNC_STUCK + | LINK_INT_ISO_STUCK | LINK_INT_ASYNC_STUCK | LINK_INT_SENT_REJECT | LINK_INT_TX_INVALID_TC | LINK_INT_GRF_OVERFLOW | LINK_INT_ITF_UNDERFLOW | LINK_INT_ATF_UNDERFLOW); - + reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ASYNC_RCV), 0); reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ASYNC_RCV), 0xa<<4); reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ASYNC_RCV), 0); @@ -1786,14 +1783,14 @@ /* attempt to enable contender bit -FIXME- would this work * elsewhere? */ reg_set_bits(lynx, GPIO_CTRL_A, 0x1); - reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); + reg_write(lynx, GPIO_DATA_BASE + 0x3c, 0x1); } else { - /* set the contender bit in the extended PHY register + /* set the contender and LCtrl bit in the extended PHY register * set. (Should check that bis 0,1,2 (=0xE0) is set * in register 2?) */ i = get_phy_reg(lynx, 4); - if (i != -1) set_phy_reg(lynx, 4, i | 0x40); + if (i != -1) set_phy_reg(lynx, 4, i | 0xc0); } @@ -1820,7 +1817,7 @@ { /* do i2c stuff */ unsigned char i2c_cmd = 0x10; - struct i2c_msg msg[2] = { { 0x50, 0, 1, &i2c_cmd }, + struct i2c_msg msg[2] = { { 0x50, 0, 1, &i2c_cmd }, { 0x50, I2C_M_RD, 20, (unsigned char*) lynx->bus_info_block } }; diff -Nru a/drivers/ieee1394/pcilynx.h b/drivers/ieee1394/pcilynx.h --- a/drivers/ieee1394/pcilynx.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/pcilynx.h Sun Apr 18 13:42:40 2004 @@ -47,7 +47,7 @@ enum { clear, have_intr, have_aux_buf, have_pcl_mem, have_1394_buffers, have_iomappings, is_host } state; - + /* remapped memory spaces */ void *registers; void *local_rom; @@ -66,9 +66,9 @@ #endif /* - * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for + * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); - * the following is an allocation bitmap + * the following is an allocation bitmap */ u8 pcl_bmap[LOCALRAM_SIZE / 1024]; @@ -167,7 +167,7 @@ #define SERIAL_EEPROM_CONTROL 0x44 #define PCI_INT_STATUS 0x48 -#define PCI_INT_ENABLE 0x4c +#define PCI_INT_ENABLE 0x4c /* status and enable have identical bit numbers */ #define PCI_INT_INT_PEND (1<<31) #define PCI_INT_FORCED_INT (1<<30) @@ -199,7 +199,7 @@ #define LBUS_ADDR_SEL_RAM (0x0<<16) #define LBUS_ADDR_SEL_ROM (0x1<<16) #define LBUS_ADDR_SEL_AUX (0x2<<16) -#define LBUS_ADDR_SEL_ZV (0x3<<16) +#define LBUS_ADDR_SEL_ZV (0x3<<16) #define GPIO_CTRL_A 0xb8 #define GPIO_CTRL_B 0xbc @@ -208,14 +208,14 @@ #define DMA_BREG(base, chan) (base + chan * 0x20) #define DMA_SREG(base, chan) (base + chan * 0x10) -#define DMA0_PREV_PCL 0x100 +#define DMA0_PREV_PCL 0x100 #define DMA1_PREV_PCL 0x120 #define DMA2_PREV_PCL 0x140 #define DMA3_PREV_PCL 0x160 #define DMA4_PREV_PCL 0x180 #define DMA_PREV_PCL(chan) (DMA_BREG(DMA0_PREV_PCL, chan)) -#define DMA0_CURRENT_PCL 0x104 +#define DMA0_CURRENT_PCL 0x104 #define DMA1_CURRENT_PCL 0x124 #define DMA2_CURRENT_PCL 0x144 #define DMA3_CURRENT_PCL 0x164 @@ -237,14 +237,14 @@ #define DMA_CHAN_STAT_SPECIALACK (1<<14) -#define DMA0_CHAN_CTRL 0x110 +#define DMA0_CHAN_CTRL 0x110 #define DMA1_CHAN_CTRL 0x130 #define DMA2_CHAN_CTRL 0x150 #define DMA3_CHAN_CTRL 0x170 #define DMA4_CHAN_CTRL 0x190 #define DMA_CHAN_CTRL(chan) (DMA_BREG(DMA0_CHAN_CTRL, chan)) /* CHAN_CTRL registers share bits */ -#define DMA_CHAN_CTRL_ENABLE (1<<31) +#define DMA_CHAN_CTRL_ENABLE (1<<31) #define DMA_CHAN_CTRL_BUSY (1<<30) #define DMA_CHAN_CTRL_LINK (1<<29) @@ -353,7 +353,7 @@ #define LINK_INT_GRF_OVERFLOW (1<<5) #define LINK_INT_ITF_UNDERFLOW (1<<4) #define LINK_INT_ATF_UNDERFLOW (1<<3) -#define LINK_INT_ISOARB_FAILED (1<<0) +#define LINK_INT_ISOARB_FAILED (1<<0) /* PHY specifics */ #define PHY_VENDORID_TI 0x800028 diff -Nru a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h --- a/drivers/ieee1394/raw1394-private.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/raw1394-private.h Sun Apr 18 13:42:41 2004 @@ -33,7 +33,7 @@ spinlock_t reqlists_lock; wait_queue_head_t poll_wait_complete; - struct list_head addr_list; + struct list_head addr_list; u8 *fcp_buffer; diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c --- a/drivers/ieee1394/raw1394.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/raw1394.c Sun Apr 18 13:42:40 2004 @@ -235,10 +235,10 @@ if (hi != NULL) { list_del(&hi->list); host_count--; - /* - FIXME: address ranges should be removed + /* + FIXME: address ranges should be removed and fileinfo states should be initialized - (including setting generation to + (including setting generation to internal-generation ...) */ } @@ -339,7 +339,7 @@ req->req.misc = 0; req->req.recvb = ptr2int(fi->iso_buffer); req->req.length = min(length, fi->iso_buffer_length); - + list_add_tail(&req->list, &reqs); } } @@ -399,7 +399,7 @@ req->req.misc = nodeid | (direction << 16); req->req.recvb = ptr2int(fi->fcp_buffer); req->req.length = length; - + list_add_tail(&req->list, &reqs); } } @@ -502,7 +502,7 @@ if (khl != NULL) { req->req.misc = host_count; req->data = (quadlet_t *)khl; - + list_for_each_entry(hi, &host_info_list, list) { khl->nodes = hi->host->node_count; strcpy(khl->name, hi->host->driver->name); @@ -536,7 +536,7 @@ req->req.error = RAW1394_ERROR_NONE; req->req.generation = get_hpsb_generation(fi->host); - req->req.misc = (fi->host->node_id << 16) + req->req.misc = (fi->host->node_id << 16) | fi->host->node_count; if (fi->protocol_version > 3) { req->req.misc |= NODEID_TO_NODE(fi->host->irm_id) << 8; @@ -635,7 +635,7 @@ req->data = &packet->header[3]; else req->data = packet->data; - + break; case RAW1394_REQ_ASYNC_WRITE: @@ -655,7 +655,7 @@ req->req.length)) req->req.error = RAW1394_ERROR_MEMFAULT; } - + req->req.length = 0; break; @@ -670,7 +670,7 @@ if (copy_from_user(packet->data, int2ptr(req->req.sendb), req->req.length)) req->req.error = RAW1394_ERROR_MEMFAULT; - + req->req.length = 0; break; @@ -807,13 +807,12 @@ int expect_response = req->req.misc >> 16; if ((header_length > req->req.length) || - (header_length < 12)) - { + (header_length < 12)) { req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.length = 0; queue_complete_req(req); return sizeof(struct raw1394_request); - } + } packet = hpsb_alloc_packet(req->req.length-header_length); req->packet = packet; @@ -886,7 +885,7 @@ entry = fi->addr_list.next; while (entry != &(fi->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (((arm_addr->start) <= (addr)) && + if (((arm_addr->start) <= (addr)) && ((arm_addr->end) >= (addr+length))) { found = 1; break; @@ -914,7 +913,7 @@ if (rcode == -1) { if (arm_addr->access_rights & ARM_READ) { if (!(arm_addr->client_transactions & ARM_READ)) { - memcpy(buffer,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), + memcpy(buffer,(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), length); DBGMSG("arm_read -> (rcode_complete)"); rcode = RCODE_COMPLETE; @@ -930,7 +929,7 @@ if (!req) { DBGMSG("arm_read -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } if (rcode == RCODE_COMPLETE) { @@ -946,7 +945,7 @@ free_pending_request(req); DBGMSG("arm_read -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } req->free_data=1; @@ -958,19 +957,19 @@ req->req.recvb = arm_addr->recvb; req->req.length = size; arm_req_resp = (struct arm_request_response *) (req->data); - arm_req = (struct arm_request *) ((byte_t *)(req->data) + + arm_req = (struct arm_request *) ((byte_t *)(req->data) + (sizeof (struct arm_request_response))); - arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + + arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); arm_req->buffer = NULL; arm_resp->buffer = NULL; if (rcode == RCODE_COMPLETE) { - arm_resp->buffer = ((byte_t *)(arm_resp) + + arm_resp->buffer = ((byte_t *)(arm_resp) + (sizeof(struct arm_response))); memcpy (arm_resp->buffer, - (arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), + (arm_addr->addr_space_buffer)+(addr-(arm_addr->start)), length); - arm_resp->buffer = int2ptr((arm_addr->recvb) + + arm_resp->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response)); @@ -985,9 +984,9 @@ arm_req->destination_nodeid = host->node_id; arm_req->tlabel = (flags >> 10) & 0x3f; arm_req->tcode = (flags >> 4) & 0x0f; - arm_req_resp->request = int2ptr((arm_addr->recvb) + + arm_req_resp->request = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response)); - arm_req_resp->response = int2ptr((arm_addr->recvb) + + arm_req_resp->response = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request)); queue_complete_req(req); @@ -1005,7 +1004,7 @@ struct list_head *entry; struct arm_addr *arm_addr = NULL; struct arm_request *arm_req = NULL; - struct arm_response *arm_resp = NULL; + struct arm_response *arm_resp = NULL; int found=0, size=0, rcode=-1, length_conflict=0; struct arm_request_response *arm_req_resp = NULL; @@ -1020,7 +1019,7 @@ entry = fi->addr_list.next; while (entry != &(fi->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (((arm_addr->start) <= (addr)) && + if (((arm_addr->start) <= (addr)) && ((arm_addr->end) >= (addr+length))) { found = 1; break; @@ -1065,7 +1064,7 @@ if (!req) { DBGMSG("arm_write -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request my be retried */ } size = sizeof(struct arm_request)+sizeof(struct arm_response) + @@ -1076,7 +1075,7 @@ free_pending_request(req); DBGMSG("arm_write -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } req->free_data=1; @@ -1088,15 +1087,15 @@ req->req.recvb = arm_addr->recvb; req->req.length = size; arm_req_resp = (struct arm_request_response *) (req->data); - arm_req = (struct arm_request *) ((byte_t *)(req->data) + + arm_req = (struct arm_request *) ((byte_t *)(req->data) + (sizeof (struct arm_request_response))); - arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + + arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + + arm_req->buffer = ((byte_t *)(arm_resp) + (sizeof(struct arm_response))); arm_resp->buffer = NULL; memcpy (arm_req->buffer, data, length); - arm_req->buffer = int2ptr((arm_addr->recvb) + + arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response)); @@ -1110,9 +1109,9 @@ arm_req->tcode = (flags >> 4) & 0x0f; arm_resp->buffer_length = 0; arm_resp->response_code = rcode; - arm_req_resp->request = int2ptr((arm_addr->recvb) + + arm_req_resp->request = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response)); - arm_req_resp->response = int2ptr((arm_addr->recvb) + + arm_req_resp->response = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request)); queue_complete_req(req); @@ -1130,7 +1129,7 @@ struct list_head *entry; struct arm_addr *arm_addr = NULL; struct arm_request *arm_req = NULL; - struct arm_response *arm_resp = NULL; + struct arm_response *arm_resp = NULL; int found=0, size=0, rcode=-1; quadlet_t old, new; struct arm_request_response *arm_req_resp = NULL; @@ -1138,12 +1137,12 @@ if (((ext_tcode & 0xFF) == EXTCODE_FETCH_ADD) || ((ext_tcode & 0xFF) == EXTCODE_LITTLE_ADD)) { DBGMSG("arm_lock called by node: %X " - "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X", + "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF , be32_to_cpu(data)); } else { DBGMSG("arm_lock called by node: %X " - "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X arg: %8.8X", + "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X arg: %8.8X", nodeid, (u16) ((addr >>32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF , be32_to_cpu(data), be32_to_cpu(arg)); } @@ -1154,7 +1153,7 @@ entry = fi->addr_list.next; while (entry != &(fi->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (((arm_addr->start) <= (addr)) && + if (((arm_addr->start) <= (addr)) && ((arm_addr->end) >= (addr+sizeof(*store)))) { found = 1; break; @@ -1199,7 +1198,7 @@ break; case (EXTCODE_BOUNDED_ADD): if (old != arg) { - new = cpu_to_be32(be32_to_cpu(data) + + new = cpu_to_be32(be32_to_cpu(data) + be32_to_cpu(old)); } else { new = old; @@ -1207,7 +1206,7 @@ break; case (EXTCODE_WRAP_ADD): if (old != arg) { - new = cpu_to_be32(be32_to_cpu(data) + + new = cpu_to_be32(be32_to_cpu(data) + be32_to_cpu(old)); } else { new = data; @@ -1224,7 +1223,7 @@ rcode = RCODE_COMPLETE; memcpy (store, &old, sizeof(*store)); memcpy ((arm_addr->addr_space_buffer)+ - (addr-(arm_addr->start)), + (addr-(arm_addr->start)), &new, sizeof(*store)); } } @@ -1239,31 +1238,31 @@ if (!req) { DBGMSG("arm_lock -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } size = sizeof(struct arm_request)+sizeof(struct arm_response) + - 3 * sizeof(*store) + + 3 * sizeof(*store) + sizeof (struct arm_request_response); /* maximum */ req->data = kmalloc(size, SLAB_ATOMIC); if (!(req->data)) { free_pending_request(req); DBGMSG("arm_lock -> rcode_conflict_error"); spin_unlock(&host_info_lock); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } req->free_data=1; arm_req_resp = (struct arm_request_response *) (req->data); - arm_req = (struct arm_request *) ((byte_t *)(req->data) + + arm_req = (struct arm_request *) ((byte_t *)(req->data) + (sizeof (struct arm_request_response))); - arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + + arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + + arm_req->buffer = ((byte_t *)(arm_resp) + (sizeof(struct arm_response))); - arm_resp->buffer = ((byte_t *)(arm_req->buffer) + + arm_resp->buffer = ((byte_t *)(arm_req->buffer) + (2* sizeof(*store))); - if ((ext_tcode == EXTCODE_FETCH_ADD) || + if ((ext_tcode == EXTCODE_FETCH_ADD) || (ext_tcode == EXTCODE_LITTLE_ADD)) { arm_req->buffer_length = sizeof(*store); memcpy (arm_req->buffer, &data, sizeof(*store)); @@ -1271,7 +1270,7 @@ } else { arm_req->buffer_length = 2 * sizeof(*store); memcpy (arm_req->buffer, &arg, sizeof(*store)); - memcpy (((arm_req->buffer) + sizeof(*store)), + memcpy (((arm_req->buffer) + sizeof(*store)), &data, sizeof(*store)); } if (rcode == RCODE_COMPLETE) { @@ -1284,7 +1283,7 @@ req->file_info = fi; req->req.type = RAW1394_REQ_ARM; req->req.generation = get_hpsb_generation(host); - req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | + req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | (ARM_LOCK & 0xFF)); req->req.tag = arm_addr->arm_tag; req->req.recvb = arm_addr->recvb; @@ -1297,16 +1296,16 @@ arm_req->tlabel = (flags >> 10) & 0x3f; arm_req->tcode = (flags >> 4) & 0x0f; arm_resp->response_code = rcode; - arm_req_resp->request = int2ptr((arm_addr->recvb) + + arm_req_resp->request = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response)); - arm_req_resp->response = int2ptr((arm_addr->recvb) + + arm_req_resp->response = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request)); - arm_req->buffer = int2ptr((arm_addr->recvb) + + arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response)); - arm_resp->buffer = int2ptr((arm_addr->recvb) + + arm_resp->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response) + @@ -1336,20 +1335,20 @@ DBGMSG("arm_lock64 called by node: %X " "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X ", nodeid, (u16) ((addr >>32) & 0xFFFF), - (u32) (addr & 0xFFFFFFFF), - ext_tcode & 0xFF , - (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), + (u32) (addr & 0xFFFFFFFF), + ext_tcode & 0xFF , + (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), (u32) (be64_to_cpu(data) & 0xFFFFFFFF)); } else { DBGMSG("arm_lock64 called by node: %X " "addr: %4.4x %8.8x extcode: %2.2X data: %8.8X %8.8X arg: " "%8.8X %8.8X ", nodeid, (u16) ((addr >>32) & 0xFFFF), - (u32) (addr & 0xFFFFFFFF), - ext_tcode & 0xFF , - (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), + (u32) (addr & 0xFFFFFFFF), + ext_tcode & 0xFF , + (u32) ((be64_to_cpu(data) >> 32) & 0xFFFFFFFF), (u32) (be64_to_cpu(data) & 0xFFFFFFFF), - (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF), + (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF), (u32) (be64_to_cpu(arg) & 0xFFFFFFFF)); } spin_lock(&host_info_lock); @@ -1359,7 +1358,7 @@ entry = fi->addr_list.next; while (entry != &(fi->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (((arm_addr->start) <= (addr)) && + if (((arm_addr->start) <= (addr)) && ((arm_addr->end) >= (addr+sizeof(*store)))) { found = 1; break; @@ -1404,7 +1403,7 @@ break; case (EXTCODE_BOUNDED_ADD): if (old != arg) { - new = cpu_to_be64(be64_to_cpu(data) + + new = cpu_to_be64(be64_to_cpu(data) + be64_to_cpu(old)); } else { new = old; @@ -1412,7 +1411,7 @@ break; case (EXTCODE_WRAP_ADD): if (old != arg) { - new = cpu_to_be64(be64_to_cpu(data) + + new = cpu_to_be64(be64_to_cpu(data) + be64_to_cpu(old)); } else { new = data; @@ -1429,9 +1428,9 @@ rcode = RCODE_COMPLETE; memcpy (store, &old, sizeof(*store)); memcpy ((arm_addr->addr_space_buffer)+ - (addr-(arm_addr->start)), + (addr-(arm_addr->start)), &new, sizeof(*store)); - } + } } } else { rcode = RCODE_TYPE_ERROR; /* function not allowed */ @@ -1444,7 +1443,7 @@ if (!req) { spin_unlock(&host_info_lock); DBGMSG("arm_lock64 -> rcode_conflict_error"); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } size = sizeof(struct arm_request)+sizeof(struct arm_response) + @@ -1455,20 +1454,20 @@ free_pending_request(req); spin_unlock(&host_info_lock); DBGMSG("arm_lock64 -> rcode_conflict_error"); - return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. + return(RCODE_CONFLICT_ERROR); /* A resource conflict was detected. The request may be retried */ } req->free_data=1; arm_req_resp = (struct arm_request_response *) (req->data); - arm_req = (struct arm_request *) ((byte_t *)(req->data) + + arm_req = (struct arm_request *) ((byte_t *)(req->data) + (sizeof (struct arm_request_response))); - arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + + arm_resp = (struct arm_response *) ((byte_t *)(arm_req) + (sizeof(struct arm_request))); - arm_req->buffer = ((byte_t *)(arm_resp) + + arm_req->buffer = ((byte_t *)(arm_resp) + (sizeof(struct arm_response))); - arm_resp->buffer = ((byte_t *)(arm_req->buffer) + + arm_resp->buffer = ((byte_t *)(arm_req->buffer) + (2* sizeof(*store))); - if ((ext_tcode == EXTCODE_FETCH_ADD) || + if ((ext_tcode == EXTCODE_FETCH_ADD) || (ext_tcode == EXTCODE_LITTLE_ADD)) { arm_req->buffer_length = sizeof(*store); memcpy (arm_req->buffer, &data, sizeof(*store)); @@ -1476,7 +1475,7 @@ } else { arm_req->buffer_length = 2 * sizeof(*store); memcpy (arm_req->buffer, &arg, sizeof(*store)); - memcpy (((arm_req->buffer) + sizeof(*store)), + memcpy (((arm_req->buffer) + sizeof(*store)), &data, sizeof(*store)); } if (rcode == RCODE_COMPLETE) { @@ -1489,7 +1488,7 @@ req->file_info = fi; req->req.type = RAW1394_REQ_ARM; req->req.generation = get_hpsb_generation(host); - req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | + req->req.misc = ( (((sizeof(*store)) << 16) & (0xFFFF0000)) | (ARM_LOCK & 0xFF)); req->req.tag = arm_addr->arm_tag; req->req.recvb = arm_addr->recvb; @@ -1502,16 +1501,16 @@ arm_req->tlabel = (flags >> 10) & 0x3f; arm_req->tcode = (flags >> 4) & 0x0f; arm_resp->response_code = rcode; - arm_req_resp->request = int2ptr((arm_addr->recvb) + + arm_req_resp->request = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response)); - arm_req_resp->response = int2ptr((arm_addr->recvb) + + arm_req_resp->response = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request)); - arm_req->buffer = int2ptr((arm_addr->recvb) + + arm_req->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response)); - arm_resp->buffer = int2ptr((arm_addr->recvb) + + arm_resp->buffer = int2ptr((arm_addr->recvb) + sizeof (struct arm_request_response) + sizeof (struct arm_request) + sizeof (struct arm_response) + @@ -1548,11 +1547,11 @@ return (-EINVAL); } /* addr-list-entry for fileinfo */ - addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL); + addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL); if (!addr) { req->req.length = 0; return (-ENOMEM); - } + } /* allocation of addr_space_buffer */ addr->addr_space_buffer = (u8 *)vmalloc(req->req.length); if (!(addr->addr_space_buffer)) { @@ -1593,7 +1592,7 @@ entry = fi_hlp->addr_list.next; while (entry != &(fi_hlp->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if ( (arm_addr->start == addr->start) && + if ( (arm_addr->start == addr->start) && (arm_addr->end == addr->end)) { DBGMSG("same host ownes same " "addressrange -> EALREADY"); @@ -1620,7 +1619,7 @@ entry = fi_hlp->addr_list.next; while (entry != &(fi_hlp->addr_list)) { arm_addr = list_entry(entry, struct arm_addr, addr_list); - if ( (arm_addr->start == addr->start) && + if ( (arm_addr->start == addr->start) && (arm_addr->end == addr->end)) { DBGMSG("another host ownes same " "addressrange"); @@ -1662,7 +1661,7 @@ vfree(addr->addr_space_buffer); kfree(addr); spin_unlock_irqrestore(&host_info_lock, flags); - return (-EALREADY); + return (-EALREADY); } spin_unlock_irqrestore(&host_info_lock, flags); free_pending_request(req); /* immediate success or fail */ @@ -1703,16 +1702,16 @@ } DBGMSG("arm_Unregister addr found"); another_host = 0; - /* another host with valid address-entry containing + /* another host with valid address-entry containing same addressrange */ list_for_each_entry(hi, &host_info_list, list) { if (hi->host != fi->host) { list_for_each_entry(fi_hlp, &hi->file_info_list, list) { entry = fi_hlp->addr_list.next; while (entry != &(fi_hlp->addr_list)) { - arm_addr = list_entry(entry, + arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (arm_addr->start == + if (arm_addr->start == addr->start) { DBGMSG("another host ownes " "same addressrange"); @@ -1735,7 +1734,7 @@ free_pending_request(req); /* immediate success or fail */ spin_unlock_irqrestore(&host_info_lock, flags); return sizeof(struct raw1394_request); - } + } retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, addr->start); if (!retval) { printk(KERN_ERR "raw1394: arm_Unregister failed -> EINVAL\n"); @@ -1863,7 +1862,7 @@ fi->notification=(u8)req->req.misc; free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ return sizeof(struct raw1394_request); - } + } /* error EINVAL (22) invalid argument */ return (-EINVAL); } @@ -1905,7 +1904,7 @@ status = csr1212_read(fi->host->csr.rom, CSR1212_CONFIG_ROM_SPACE_OFFSET, data, req->req.length); - if (copy_to_user(int2ptr(req->req.recvb), data, + if (copy_to_user(int2ptr(req->req.recvb), data, req->req.length)) ret = -EFAULT; if (copy_to_user(int2ptr(req->req.tag), &fi->host->csr.rom->cache_head->len, @@ -1914,7 +1913,7 @@ if (copy_to_user(int2ptr(req->req.address), &fi->host->csr.generation, sizeof(fi->host->csr.generation))) ret = -EFAULT; - if (copy_to_user(int2ptr(req->req.sendb), &status, + if (copy_to_user(int2ptr(req->req.sendb), &status, sizeof(status))) ret = -EFAULT; kfree(data); @@ -1929,14 +1928,14 @@ int ret=sizeof(struct raw1394_request); quadlet_t *data = kmalloc(req->req.length, SLAB_KERNEL); if (!data) return -ENOMEM; - if (copy_from_user(data,int2ptr(req->req.sendb), + if (copy_from_user(data,int2ptr(req->req.sendb), req->req.length)) { ret= -EFAULT; } else { - int status = hpsb_update_config_rom(fi->host, - data, req->req.length, + int status = hpsb_update_config_rom(fi->host, + data, req->req.length, (unsigned char) req->req.misc); - if (copy_to_user(int2ptr(req->req.recvb), + if (copy_to_user(int2ptr(req->req.recvb), &status, sizeof(status))) ret = -ENOMEM; } @@ -2033,7 +2032,7 @@ if (ret == CSR1212_SUCCESS) { ret = hpsb_update_config_rom_image(fi->host); - if (ret >= 0 && copy_to_user(int2ptr(req->req.recvb), + if (ret >= 0 && copy_to_user(int2ptr(req->req.recvb), &dr, sizeof(dr))) { ret = -ENOMEM; } @@ -2044,7 +2043,7 @@ if (ret >= 0) { /* we have to free the request, because we queue no response, - * and therefore nobody will free it */ + * and therefore nobody will free it */ free_pending_request(req); return sizeof(struct raw1394_request); } else { @@ -2362,7 +2361,7 @@ &fi->iso_handle->infos[packet], sizeof(struct raw1394_iso_packet_info))) return -EFAULT; - + packet = (packet + 1) % fi->iso_handle->buf_packets; } @@ -2534,7 +2533,7 @@ fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL); if (fi == NULL) return -ENOMEM; - + memset(fi, 0, sizeof(struct file_info)); fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */ @@ -2588,16 +2587,16 @@ another_host = 0; lh = fi->addr_list.next; addr = list_entry(lh, struct arm_addr, addr_list); - /* another host with valid address-entry containing + /* another host with valid address-entry containing same addressrange? */ list_for_each_entry(hi, &host_info_list, list) { if (hi->host != fi->host) { list_for_each_entry(fi_hlp, &hi->file_info_list, list) { entry = fi_hlp->addr_list.next; while (entry != &(fi_hlp->addr_list)) { - arm_addr = list_entry(entry, + arm_addr = list_entry(entry, struct arm_addr, addr_list); - if (arm_addr->start == + if (arm_addr->start == addr->start) { DBGMSG("raw1394_release: " "another host ownes " @@ -2726,13 +2725,13 @@ static struct cdev raw1394_cdev; static struct file_operations raw1394_fops = { .owner = THIS_MODULE, - .read = raw1394_read, + .read = raw1394_read, .write = raw1394_write, .mmap = raw1394_mmap, .ioctl = raw1394_ioctl, - .poll = raw1394_poll, - .open = raw1394_open, - .release = raw1394_release, + .poll = raw1394_poll, + .open = raw1394_open, + .release = raw1394_release, }; static int __init init_raw1394(void) @@ -2746,9 +2745,9 @@ cdev_init(&raw1394_cdev, &raw1394_fops); raw1394_cdev.owner = THIS_MODULE; + kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME); ret = cdev_add(&raw1394_cdev, IEEE1394_RAW1394_DEV, 1); if (ret) { - /* jmc: leaves reference to (static) raw1394_cdev */ HPSB_ERR("raw1394 failed to register minor device block"); devfs_remove(RAW1394_DEVICE_NAME); hpsb_unregister_highlevel(&raw1394_highlevel); diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/sbp2.c Sun Apr 18 13:42:40 2004 @@ -78,7 +78,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 1170 $ Ben Collins "; + "$Rev: 1205 $ Ben Collins "; /* * Module load parameter definitions @@ -137,7 +137,7 @@ * if your sbp2 device is not properly handling the SCSI inquiry command. * This hack makes the inquiry look more like a typical MS Windows * inquiry. - * + * * If force_inquiry_hack=1 is required for your device to work, * please submit the logged sbp2_firmware_revision value of this device to * the linux1394-devel mailing list. @@ -206,7 +206,7 @@ #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) #define SBP2_WARN(fmt, args...) HPSB_WARN("sbp2: "fmt, ## args) -#else +#else #define SBP2_DEBUG(fmt, args...) #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) #define SBP2_NOTICE(fmt, args...) HPSB_NOTICE("sbp2: "fmt, ## args) @@ -226,7 +226,7 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, u32 scsi_status, Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)); - + static Scsi_Host_Template scsi_driver_template; const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC }; @@ -409,7 +409,7 @@ struct sbp2_command_info *command; orbs = serialize_io ? 2 : SBP2_MAX_CMDS; - + spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); for (i = 0; i < orbs; i++) { command = (struct sbp2_command_info *) @@ -445,7 +445,7 @@ struct list_head *lh, *next; struct sbp2_command_info *command; unsigned long flags; - + spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); if (!list_empty(&scsi_id->sbp2_command_orb_completed)) { list_for_each_safe(lh, next, &scsi_id->sbp2_command_orb_completed) { @@ -468,7 +468,7 @@ return; } -/* +/* * This function finds the sbp2_command for a given outstanding command * orb.Only looks at the inuse list. */ @@ -494,7 +494,7 @@ return(NULL); } -/* +/* * This function finds the sbp2_command for a given outstanding SCpnt. * Only looks at the inuse list. */ @@ -520,8 +520,8 @@ * This function allocates a command orb used to send a scsi command. */ static struct sbp2_command_info *sbp2util_allocate_command_orb( - struct scsi_id_instance_data *scsi_id, - Scsi_Cmnd *Current_SCpnt, + struct scsi_id_instance_data *scsi_id, + Scsi_Cmnd *Current_SCpnt, void (*Current_done)(Scsi_Cmnd *)) { struct list_head *lh; @@ -647,8 +647,8 @@ SBP2_DEBUG("sbp2_update"); if (sbp2_reconnect_device(scsi_id)) { - - /* + + /* * Ok, reconnect has failed. Perhaps we didn't * reconnect fast enough. Try doing a regular login, but * first do a logout just in case of any weirdness. @@ -658,7 +658,7 @@ if (sbp2_login_device(scsi_id)) { /* Login failed too, just fail, and the backend * will call our sbp2_remove for us */ - SBP2_INFO("sbp2_reconnect_device failed!"); + SBP2_ERR("Failed to reconnect to sbp2 device!"); return -EBUSY; } } @@ -851,7 +851,7 @@ scsi_id->query_logins_orb_dma); SBP2_DMA_FREE("query logins ORB DMA"); } - + if (scsi_id->logout_orb) { pci_free_consistent(hi->host->pdev, sizeof(struct sbp2_logout_orb), @@ -905,7 +905,6 @@ * allows someone else to login instead. One second makes sense. */ set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); - /* * Login to the sbp-2 device @@ -920,12 +919,12 @@ * Set max retries to something large on the device */ sbp2_set_busy_timeout(scsi_id); - + /* * Do a SBP-2 fetch agent reset */ sbp2_agent_reset(scsi_id, 1); - + /* * Get the max speed and packet size that we can use */ @@ -1157,14 +1156,14 @@ max_logins = RESPONSE_GET_MAX_LOGINS(scsi_id->query_logins_response->length_max_logins); SBP2_DEBUG("Maximum concurrent logins supported: %d", max_logins); - + active_logins = RESPONSE_GET_ACTIVE_LOGINS(scsi_id->query_logins_response->length_max_logins); SBP2_DEBUG("Number of active logins: %d", active_logins); - + if (active_logins >= max_logins) { return(-EIO); } - + return 0; } @@ -1172,7 +1171,7 @@ * This function is called in order to login to a particular SBP-2 device, * after a bus reset. */ -static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) +static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) { struct sbp2scsi_host_info *hi = scsi_id->hi; quadlet_t data[2]; @@ -1192,7 +1191,7 @@ } /* Set-up login ORB, assume no password */ - scsi_id->login_orb->password_hi = 0; + scsi_id->login_orb->password_hi = 0; scsi_id->login_orb->password_lo = 0; SBP2_DEBUG("sbp2_login_device: password_hi/lo initialized"); @@ -1216,7 +1215,7 @@ ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response)); SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized"); - scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + + scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI); @@ -1229,7 +1228,7 @@ SBP2_DEBUG("sbp2_login_device: orb byte-swapped"); - sbp2util_packet_dump(scsi_id->login_orb, sizeof(struct sbp2_login_orb), + sbp2util_packet_dump(scsi_id->login_orb, sizeof(struct sbp2_login_orb), "sbp2 login orb", scsi_id->login_orb_dma); /* @@ -1255,7 +1254,7 @@ SBP2_DEBUG("sbp2_login_device: written"); /* - * Wait for login status (up to 20 seconds)... + * Wait for login status (up to 20 seconds)... */ if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) { SBP2_ERR("Error logging into SBP-2 device - login timed-out"); @@ -1310,10 +1309,11 @@ * This function is called in order to logout from a particular SBP-2 * device, usually called during driver unload. */ -static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) +static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) { struct sbp2scsi_host_info *hi = scsi_id->hi; quadlet_t data[2]; + int error; SBP2_DEBUG("sbp2_logout_device"); @@ -1332,7 +1332,7 @@ scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1); scsi_id->logout_orb->reserved5 = 0x0; - scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + + scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI); @@ -1342,7 +1342,7 @@ */ sbp2util_cpu_to_be32_buffer(scsi_id->logout_orb, sizeof(struct sbp2_logout_orb)); - sbp2util_packet_dump(scsi_id->logout_orb, sizeof(struct sbp2_logout_orb), + sbp2util_packet_dump(scsi_id->logout_orb, sizeof(struct sbp2_logout_orb), "sbp2 logout orb", scsi_id->logout_orb_dma); /* @@ -1354,10 +1354,15 @@ atomic_set(&scsi_id->sbp2_login_complete, 0); - hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); + error = hpsb_node_write(scsi_id->ne, + scsi_id->sbp2_management_agent_addr, + data, 8); + if (error) + return error; /* Wait for device to logout...1 second. */ - sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ); + if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) + return -EIO; SBP2_INFO("Logged out of SBP-2 device"); @@ -1369,10 +1374,11 @@ * This function is called in order to reconnect to a particular SBP-2 * device, after a bus reset. */ -static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) +static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) { struct sbp2scsi_host_info *hi = scsi_id->hi; quadlet_t data[2]; + int error; SBP2_DEBUG("sbp2_reconnect_device"); @@ -1392,7 +1398,7 @@ scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1); scsi_id->reconnect_orb->reserved5 = 0x0; - scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + + scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); scsi_id->reconnect_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI); @@ -1402,7 +1408,7 @@ */ sbp2util_cpu_to_be32_buffer(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb)); - sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), + sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), "sbp2 reconnect orb", scsi_id->reconnect_orb_dma); /* @@ -1419,7 +1425,11 @@ atomic_set(&scsi_id->sbp2_login_complete, 0); - hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); + error = hpsb_node_write(scsi_id->ne, + scsi_id->sbp2_management_agent_addr, + data, 8); + if (error) + return error; /* * Wait for reconnect status (up to 1 second)... @@ -1448,7 +1458,7 @@ return(-EIO); } - SBP2_INFO("Reconnected to SBP-2 device"); + HPSB_DEBUG("Reconnected to SBP-2 device"); return(0); @@ -1456,7 +1466,7 @@ /* * This function is called in order to set the busy timeout (number of - * retries to attempt) on the sbp2 device. + * retries to attempt) on the sbp2 device. */ static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id) { @@ -1480,7 +1490,7 @@ /* * This function is called to parse sbp2 device's config rom unit * directory. Used to determine things like sbp2 management agent offset, - * and command set used (SCSI or RBC). + * and command set used (SCSI or RBC). */ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, struct unit_directory *ud) @@ -1638,18 +1648,18 @@ scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code], (u8)(hi->host->csr.max_rec - 1)); - SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", - NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), - hpsb_speedto_str[scsi_id->speed_code], - 1 << ((u32)scsi_id->max_payload_size + 2)); + HPSB_DEBUG("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]", + NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid), + hpsb_speedto_str[scsi_id->speed_code], + 1 << ((u32)scsi_id->max_payload_size + 2)); return(0); } /* - * This function is called in order to perform a SBP-2 agent reset. + * This function is called in order to perform a SBP-2 agent reset. */ -static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) +static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) { quadlet_t data; u64 addr; @@ -1690,7 +1700,7 @@ unchar *scsi_cmd, unsigned int scsi_use_sg, unsigned int scsi_request_bufflen, - void *scsi_request_buffer, + void *scsi_request_buffer, unsigned char scsi_dir) { struct sbp2scsi_host_info *hi = scsi_id->hi; @@ -1734,7 +1744,7 @@ case SCSI_DATA_UNKNOWN: default: SBP2_ERR("SCSI data transfer direction not specified. " - "Update the SBP2 direction table in sbp2.h if " + "Update the SBP2 direction table in sbp2.h if " "necessary for your application"); print_command (scsi_cmd); orb_direction = sbp2scsi_direction_table[*scsi_cmd]; @@ -1805,12 +1815,12 @@ while (sg_len) { scatter_gather_element[sg_count].segment_base_lo = sg_addr; if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { - scatter_gather_element[sg_count].length_segment_base_hi = + scatter_gather_element[sg_count].length_segment_base_hi = PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; } else { - scatter_gather_element[sg_count].length_segment_base_hi = + scatter_gather_element[sg_count].length_segment_base_hi = PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); sg_len = 0; } @@ -1821,14 +1831,14 @@ /* Number of page table (s/g) elements */ command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); - sbp2util_packet_dump(scatter_gather_element, - (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, + sbp2util_packet_dump(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, "sbp2 s/g list", command->sge_dma); /* * Byte swap page tables if necessary */ - sbp2util_cpu_to_be32_buffer(scatter_gather_element, + sbp2util_cpu_to_be32_buffer(scatter_gather_element, (sizeof(struct sbp2_unrestricted_page_table)) * sg_count); @@ -1871,7 +1881,7 @@ /* * Need to turn this into page tables, since the * buffer is too large. - */ + */ command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); command_orb->data_descriptor_lo = command->sge_dma; @@ -1889,12 +1899,12 @@ while (sg_len) { scatter_gather_element[sg_count].segment_base_lo = sg_addr; if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { - scatter_gather_element[sg_count].length_segment_base_hi = + scatter_gather_element[sg_count].length_segment_base_hi = PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; } else { - scatter_gather_element[sg_count].length_segment_base_hi = + scatter_gather_element[sg_count].length_segment_base_hi = PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); sg_len = 0; } @@ -1904,14 +1914,14 @@ /* Number of page table (s/g) elements */ command_orb->misc |= ORB_SET_DATA_SIZE(sg_count); - sbp2util_packet_dump(scatter_gather_element, - (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, + sbp2util_packet_dump(scatter_gather_element, + (sizeof(struct sbp2_unrestricted_page_table)) * sg_count, "sbp2 s/g list", command->sge_dma); /* * Byte swap page tables if necessary */ - sbp2util_cpu_to_be32_buffer(scatter_gather_element, + sbp2util_cpu_to_be32_buffer(scatter_gather_element, (sizeof(struct sbp2_unrestricted_page_table)) * sg_count); @@ -1932,9 +1942,9 @@ return(0); } - + /* - * This function is called in order to begin a regular SBP-2 command. + * This function is called in order to begin a regular SBP-2 command. */ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command) @@ -2019,7 +2029,7 @@ } /* - * This function is called in order to begin a regular SBP-2 command. + * This function is called in order to begin a regular SBP-2 command. */ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) @@ -2046,8 +2056,8 @@ /* * The scsi stack sends down a request_bufflen which does not match the - * length field in the scsi cdb. This causes some sbp2 devices to - * reject this inquiry command. Fix the request_bufflen. + * length field in the scsi cdb. This causes some sbp2 devices to + * reject this inquiry command. Fix the request_bufflen. */ if (*cmd == INQUIRY) { if (force_inquiry_hack || scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) @@ -2061,14 +2071,14 @@ */ sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg, request_bufflen, SCpnt->request_buffer, - SCpnt->sc_data_direction); + SCpnt->sc_data_direction); /* * Update our cdb if necessary (to handle sbp2 RBC command set * differences). This is where the command set hacks go! =) */ sbp2_check_sbp2_command(scsi_id, command->command_orb.cdb); - sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb), + sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb), "sbp2 command orb", command->command_orb_dma); /* @@ -2080,7 +2090,7 @@ * Link up the orb, and ring the doorbell if needed */ sbp2_link_orb_command(scsi_id, command); - + return(0); } @@ -2097,13 +2107,13 @@ SBP2_DEBUG("sbp2_check_sbp2_command"); switch (*cmd) { - + case READ_6: if (sbp2_command_conversion_device_type(device_type)) { SBP2_DEBUG("Convert READ_6 to READ_10"); - + /* * Need to turn read_6 into read_10 */ @@ -2117,7 +2127,7 @@ new_cmd[7] = 0x0; new_cmd[8] = cmd[4]; new_cmd[9] = cmd[5]; - + memcpy(cmd, new_cmd, 10); } @@ -2129,7 +2139,7 @@ if (sbp2_command_conversion_device_type(device_type)) { SBP2_DEBUG("Convert WRITE_6 to WRITE_10"); - + /* * Need to turn write_6 into write_10 */ @@ -2143,7 +2153,7 @@ new_cmd[7] = 0x0; new_cmd[8] = cmd[4]; new_cmd[9] = cmd[5]; - + memcpy(cmd, new_cmd, 10); } @@ -2169,7 +2179,7 @@ new_cmd[7] = 0x0; new_cmd[8] = cmd[4]; new_cmd[9] = cmd[5]; - + memcpy(cmd, new_cmd, 10); } @@ -2232,7 +2242,7 @@ SBP2_DEBUG("sbp2_check_sbp2_response"); switch (SCpnt->cmnd[0]) { - + case INQUIRY: /* @@ -2270,7 +2280,7 @@ case MODE_SENSE: if (sbp2_command_conversion_device_type(device_type)) { - + SBP2_DEBUG("Modify mode sense response (10 byte version)"); scsi_buf[0] = scsi_buf[1]; /* Mode data length */ @@ -2278,7 +2288,6 @@ scsi_buf[2] = scsi_buf[3]; /* Device specific parameter */ scsi_buf[3] = scsi_buf[7]; /* Block descriptor length */ memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]); - } break; @@ -2342,7 +2351,7 @@ } /* - * Put response into scsi_id status fifo... + * Put response into scsi_id status fifo... */ memcpy(&scsi_id->status_block, data, length); @@ -2394,7 +2403,7 @@ if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) { /* - * Initiate a fetch agent reset. + * Initiate a fetch agent reset. */ SBP2_DEBUG("Dead bit set - initiating fetch agent reset"); sbp2_agent_reset(scsi_id, 0); @@ -2405,7 +2414,7 @@ /* * Check here to see if there are no commands in-use. If there are none, we can - * null out last orb so that next time around we write directly to the orb pointer... + * null out last orb so that next time around we write directly to the orb pointer... * Quick start saves one 1394 bus transaction. */ if (list_empty(&scsi_id->sbp2_command_orb_inuse)) { @@ -2413,8 +2422,8 @@ } } else { - - /* + + /* * It's probably a login/logout/reconnect status. */ if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) || @@ -2443,10 +2452,10 @@ **************************************/ /* - * This routine is the main request entry routine for doing I/O. It is + * This routine is the main request entry routine for doing I/O. It is * called from the scsi stack directly. */ -static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) +static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { struct scsi_id_instance_data *scsi_id = (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; @@ -2521,7 +2530,7 @@ * This function is called in order to complete all outstanding SBP-2 * commands (in case of resets, etc.). */ -static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id, +static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id, u32 status) { struct sbp2scsi_host_info *hi = scsi_id->hi; @@ -2581,7 +2590,7 @@ SBP2_ERR("Bus reset in progress - retry command later"); return; } - + /* * Switch on scsi status */ @@ -2650,7 +2659,7 @@ * or hot-plug... */ #if 0 - if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && + if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) { SBP2_DEBUG("UNIT ATTENTION - return busy"); SCpnt->result = DID_BUS_BUSY << 16; @@ -2680,7 +2689,7 @@ * Called by scsi stack when something has really gone wrong. Usually * called when a command has timed-out for some reason. */ -static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) +static int sbp2scsi_abort (Scsi_Cmnd *SCpnt) { struct scsi_id_instance_data *scsi_id = (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; @@ -2689,7 +2698,7 @@ SBP2_ERR("aborting sbp2 command"); print_command (SCpnt->cmnd); - + if (scsi_id) { /* @@ -2716,10 +2725,10 @@ } /* - * Initiate a fetch agent reset. + * Initiate a fetch agent reset. */ sbp2_agent_reset(scsi_id, 0); - sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); + sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); } return(SUCCESS); @@ -2728,7 +2737,7 @@ /* * Called by scsi stack when something has really gone wrong. */ -static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) +static int sbp2scsi_reset (Scsi_Cmnd *SCpnt) { struct scsi_id_instance_data *scsi_id = (struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0]; diff -Nru a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h --- a/drivers/ieee1394/sbp2.h Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/sbp2.h Sun Apr 18 13:42:40 2004 @@ -271,7 +271,7 @@ #endif /* - * SCSI direction table... + * SCSI direction table... * (now used as a back-up in case the direction passed down from above is "unknown") * * DIN = IN data direction @@ -285,7 +285,7 @@ #define DIN ORB_DIRECTION_READ_FROM_MEDIA #define DOU ORB_DIRECTION_WRITE_TO_MEDIA #define DNO ORB_DIRECTION_NO_DATA_TRANSFER -#define DUN DIN +#define DUN DIN static unchar sbp2scsi_direction_table[0x100] = { DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, @@ -316,8 +316,8 @@ CMD_DMA_SINGLE }; -/* - * Encapsulates all the info necessary for an outstanding command. +/* + * Encapsulates all the info necessary for an outstanding command. */ struct sbp2_command_info { @@ -386,12 +386,12 @@ u32 sbp2_device_type_and_lun; u32 sbp2_firmware_revision; - /* + /* * Variable used for logins, reconnects, logouts, query logins */ atomic_t sbp2_login_complete; - /* + /* * Pool of command orbs, so we can have more than overlapped command per id */ spinlock_t sbp2_command_orb_lock; @@ -433,8 +433,8 @@ static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_id); static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb); static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt); -static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id, - Scsi_Cmnd *Current_SCpnt, +static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id, + Scsi_Cmnd *Current_SCpnt, void (*Current_done)(Scsi_Cmnd *)); static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command); @@ -455,8 +455,8 @@ */ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id); static int sbp2_login_device(struct scsi_id_instance_data *scsi_id); -static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id); -static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id); +static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id); +static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id); static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data, u64 addr, size_t length, u16 flags); static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait); @@ -465,7 +465,7 @@ unchar *scsi_cmd, unsigned int scsi_use_sg, unsigned int scsi_request_bufflen, - void *scsi_request_buffer, + void *scsi_request_buffer, unsigned char scsi_dir); static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command); diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c --- a/drivers/ieee1394/video1394.c Sun Apr 18 13:42:40 2004 +++ b/drivers/ieee1394/video1394.c Sun Apr 18 13:42:40 2004 @@ -102,7 +102,7 @@ unsigned int *buffer_status; struct timeval *buffer_time; /* time when the buffer was received */ - unsigned int *last_used_cmd; /* For ISO Transmit with + unsigned int *last_used_cmd; /* For ISO Transmit with variable sized packets only ! */ int ctrlClear; int ctrlSet; @@ -154,7 +154,7 @@ static int free_dma_iso_ctx(struct dma_iso_ctx *d) { int i; - + DBGMSG(d->ohci->host->id, "Freeing dma_iso_ctx %d", d->ctx); ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); @@ -260,7 +260,7 @@ d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx; d->ctxMatch = OHCI1394_IsoRcvContextMatch+32*d->ctx; - d->ir_prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *), + d->ir_prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *), GFP_KERNEL); if (d->ir_prg == NULL) { @@ -273,7 +273,7 @@ d->nb_cmd = d->buf_size / PAGE_SIZE + 1; d->left_size = (d->frame_size % PAGE_SIZE) ? d->frame_size % PAGE_SIZE : PAGE_SIZE; - + for (i = 0;i < d->num_desc; i++) { if (dma_prog_region_alloc(&d->prg_reg[i], d->nb_cmd * sizeof(struct dma_cmd), ohci->dev)) { @@ -289,21 +289,21 @@ d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx; d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx; - d->it_prg = kmalloc(d->num_desc * sizeof(struct it_dma_prg *), + d->it_prg = kmalloc(d->num_desc * sizeof(struct it_dma_prg *), GFP_KERNEL); if (d->it_prg == NULL) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma it prg"); free_dma_iso_ctx(d); return NULL; } memset(d->it_prg, 0, d->num_desc*sizeof(struct it_dma_prg *)); - + d->packet_size = packet_size; if (PAGE_SIZE % packet_size || packet_size>4096) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Packet size %d (page_size: %ld) " "not yet supported\n", packet_size, PAGE_SIZE); @@ -362,7 +362,7 @@ memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); memset(d->next_buffer, -1, d->num_desc * sizeof(int)); - + spin_lock_init(&d->lock); PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " @@ -412,9 +412,9 @@ (unsigned long)d->dma.kvirt)); ir_prg[1].branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(ir_reg, 2 * sizeof(struct dma_cmd)) & 0xfffffff0) | 0x1); - + for (i = 2; i < d->nb_cmd - 1; i++) { - ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | + ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_BRANCH | PAGE_SIZE); ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf+(i-1)*PAGE_SIZE) - @@ -426,21 +426,21 @@ } /* The last descriptor will generate an interrupt */ - ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | + ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size); ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt)); - } else { + } else { /* Only one DMA page is used. Read d->left_size immediately and */ /* generate an interrupt as this is also the last page. */ - ir_prg[1].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | + ir_prg[1].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | DMA_CTL_IRQ | DMA_CTL_BRANCH | (d->left_size-4)); ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, (buf + 4) - (unsigned long)d->dma.kvirt)); } } - + static void initialize_dma_ir_ctx(struct dma_iso_ctx *d, int tag, int flags) { struct ti_ohci *ohci = (struct ti_ohci *)d->ohci; @@ -462,13 +462,13 @@ reg_write(ohci, d->ctrlSet, 0x80000000); /* Set isoch header */ - if (flags & VIDEO1394_INCLUDE_ISO_HEADERS) + if (flags & VIDEO1394_INCLUDE_ISO_HEADERS) reg_write(ohci, d->ctrlSet, 0x40000000); - /* Set the context match register to match on all tags, + /* Set the context match register to match on all tags, sync for sync tag, and listen to d->channel */ reg_write(ohci, d->ctxMatch, 0xf0000000|((tag&0xf)<<8)|d->channel); - + /* Set up isoRecvIntMask to generate interrupts */ reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1<ctx); } @@ -524,9 +524,9 @@ timeStamp = ((cycleTimer & 0x0fff) + d->syt_offset); /* 11059 = 450 us */ timeStamp = (timeStamp % 3072 + ((timeStamp / 3072) << 12) + (cycleTimer & 0xf000)) & 0xffff; - - buf[6] = timeStamp >> 8; - buf[7] = timeStamp & 0xff; + + buf[6] = timeStamp >> 8; + buf[7] = timeStamp & 0xff; /* if first packet is empty packet, then put timestamp into the next full one too */ if ( (le32_to_cpu(d->it_prg[n][0].data[1]) >>16) == 0x008) { @@ -557,7 +557,7 @@ #if 0 printk("curr: %d, next: %d, cycleTimer: %08x timeStamp: %08x\n", curr, n, cycleTimer, timeStamp); -#endif +#endif } void wakeup_dma_it_ctx(unsigned long l) @@ -569,7 +569,7 @@ spin_lock(&d->lock); for (i = 0; i < d->num_desc; i++) { - if (d->it_prg[i][d->last_used_cmd[i]].end.status & + if (d->it_prg[i][d->last_used_cmd[i]].end.status & cpu_to_le32(0xFFFF0000)) { int next = d->next_buffer[i]; put_timestamp(ohci, d, next); @@ -592,23 +592,23 @@ int i; d->last_used_cmd[n] = d->nb_cmd - 1; for (i=0;inb_cmd;i++) { - + it_prg[i].begin.control = cpu_to_le32(DMA_CTL_OUTPUT_MORE | DMA_CTL_IMMEDIATE | 8) ; it_prg[i].begin.address = 0; - + it_prg[i].begin.status = 0; - + it_prg[i].data[0] = cpu_to_le32( - (IEEE1394_SPEED_100 << 16) + (IEEE1394_SPEED_100 << 16) | (/* tag */ 1 << 14) - | (d->channel << 8) + | (d->channel << 8) | (TCODE_ISO_DATA << 4)); if (i==0) it_prg[i].data[0] |= cpu_to_le32(sync_tag); it_prg[i].data[1] = cpu_to_le32(d->packet_size << 16); it_prg[i].data[2] = 0; it_prg[i].data[3] = 0; - + it_prg[i].end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH); it_prg[i].end.address = @@ -617,15 +617,15 @@ if (inb_cmd-1) { it_prg[i].end.control |= cpu_to_le32(d->packet_size); - it_prg[i].begin.branchAddress = + it_prg[i].begin.branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); - it_prg[i].end.branchAddress = + it_prg[i].end.branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(it_reg, (i + 1) * sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); } else { /* the last prg generates an interrupt */ - it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | + it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | DMA_CTL_IRQ | d->left_size); /* the last prg doesn't branch */ it_prg[i].begin.branchAddress = 0; @@ -657,7 +657,7 @@ } else { size = packet_sizes[i]; } - it_prg[i].data[1] = cpu_to_le32(size << 16); + it_prg[i].data[1] = cpu_to_le32(size << 16); it_prg[i].end.control = cpu_to_le32(DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH); if (i < d->nb_cmd-1 && packet_sizes[i+1] != 0) { @@ -670,7 +670,7 @@ sizeof(struct it_dma_prg)) & 0xfffffff0) | 0x3); } else { /* the last prg generates an interrupt */ - it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | + it_prg[i].end.control |= cpu_to_le32(DMA_CTL_UPDATE | DMA_CTL_IRQ | size); /* the last prg doesn't branch */ it_prg[i].begin.branchAddress = 0; @@ -694,7 +694,7 @@ for (i=0;inum_desc;i++) initialize_dma_it_prg(d, i, sync_tag); - + /* Set up isoRecvIntMask to generate interrupts */ reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1<ctx); } @@ -731,9 +731,9 @@ mask = mask << 1; } } - + if (v.channel<0 || v.channel>(ISO_CHANNELS-1)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Iso channel %d out of bounds", v.channel); return -EFAULT; } @@ -743,7 +743,7 @@ (u32)(ohci->ISO_channel_usage>>32), (u32)(ohci->ISO_channel_usage&0xffffffff)); if (ohci->ISO_channel_usage & mask) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Channel %d is already taken", v.channel); return -EFAULT; } @@ -762,19 +762,19 @@ } if (v.nb_buffers * v.buf_size > VIDEO1394_MAX_SIZE) { - PRINT(KERN_ERR, ohci->host->id, - "%d buffers of size %d bytes is too big", + PRINT(KERN_ERR, ohci->host->id, + "%d buffers of size %d bytes is too big", v.nb_buffers, v.buf_size); return -EFAULT; } if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, - v.nb_buffers, v.buf_size, + v.nb_buffers, v.buf_size, v.channel, 0); if (d == NULL) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Couldn't allocate ir context"); return -EFAULT; } @@ -785,21 +785,21 @@ v.buf_size = d->buf_size; list_add_tail(&d->link, &ctx->context_list); - PRINT(KERN_INFO, ohci->host->id, + PRINT(KERN_INFO, ohci->host->id, "iso context %d listen on channel %d", d->ctx, v.channel); } else { d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, - v.nb_buffers, v.buf_size, + v.nb_buffers, v.buf_size, v.channel, v.packet_size); if (d == NULL) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Couldn't allocate it context"); return -EFAULT; } - initialize_dma_it_ctx(d, v.sync_tag, + initialize_dma_it_ctx(d, v.sync_tag, v.syt_offset, v.flags); ctx->current_ctx = d; @@ -808,7 +808,7 @@ list_add_tail(&d->link, &ctx->context_list); - PRINT(KERN_INFO, ohci->host->id, + PRINT(KERN_INFO, ohci->host->id, "Iso context %d talk on channel %d", d->ctx, v.channel); } @@ -818,7 +818,7 @@ return 0; } - case VIDEO1394_IOC_UNLISTEN_CHANNEL: + case VIDEO1394_IOC_UNLISTEN_CHANNEL: case VIDEO1394_IOC_UNTALK_CHANNEL: { int channel; @@ -829,13 +829,13 @@ return -EFAULT; if (channel<0 || channel>(ISO_CHANNELS-1)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Iso channel %d out of bound", channel); return -EFAULT; } mask = (u64)0x1<ISO_channel_usage & mask)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Channel %d is not being used", channel); return -EFAULT; } @@ -852,7 +852,7 @@ PRINT(KERN_INFO, ohci->host->id, "Iso context %d " "stop talking on channel %d", d->ctx, channel); free_dma_iso_ctx(d); - + return 0; } case VIDEO1394_IOC_LISTEN_QUEUE_BUFFER: @@ -866,20 +866,20 @@ d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); if ((v.buffer<0) || (v.buffer>d->num_desc)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EFAULT; } - + spin_lock_irqsave(&d->lock,flags); if (d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d is already used",v.buffer); spin_unlock_irqrestore(&d->lock,flags); return -EFAULT; } - + d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; if (d->last_buffer>=0) @@ -893,7 +893,7 @@ spin_unlock_irqrestore(&d->lock,flags); - if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) + if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) { DBGMSG(ohci->host->id, "Starting iso DMA ctx=%d",d->ctx); @@ -907,13 +907,13 @@ else { /* Wake up dma context if necessary */ if (!(reg_read(ohci, d->ctrlSet) & 0x400)) { - PRINT(KERN_INFO, ohci->host->id, + PRINT(KERN_INFO, ohci->host->id, "Waking up iso dma ctx=%d", d->ctx); reg_write(ohci, d->ctrlSet, 0x1000); } } return 0; - + } case VIDEO1394_IOC_LISTEN_WAIT_BUFFER: case VIDEO1394_IOC_LISTEN_POLL_BUFFER: @@ -928,13 +928,13 @@ d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); if ((v.buffer<0) || (v.buffer>d->num_desc)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EFAULT; } /* - * I change the way it works so that it returns + * I change the way it works so that it returns * the last received frame. */ spin_lock_irqsave(&d->lock, flags); @@ -961,7 +961,7 @@ } } #else - if (wait_event_interruptible(d->waitq, + if (wait_event_interruptible(d->waitq, d->buffer_status[v.buffer] == VIDEO1394_BUFFER_READY) == -ERESTARTSYS) @@ -970,7 +970,7 @@ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE; break; default: - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d is not queued",v.buffer); spin_unlock_irqrestore(&d->lock, flags); return -EFAULT; @@ -1011,16 +1011,16 @@ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if ((v.buffer<0) || (v.buffer>d->num_desc)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EFAULT; } - + if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { unsigned int *psizes; int buf_size = d->nb_cmd * sizeof(unsigned int); - if (copy_from_user(&qv, (void *)arg, sizeof(qv))) + if (copy_from_user(&qv, (void *)arg, sizeof(qv))) return -EFAULT; psizes = kmalloc(buf_size, GFP_KERNEL); @@ -1038,14 +1038,14 @@ spin_lock_irqsave(&d->lock,flags); if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d is already used",v.buffer); spin_unlock_irqrestore(&d->lock,flags); if (qv.packet_sizes) kfree(qv.packet_sizes); return -EFAULT; } - + if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { initialize_dma_it_prg_var_packet_queue( d, v.buffer, qv.packet_sizes, @@ -1056,7 +1056,7 @@ if (d->last_buffer >= 0) { d->it_prg[d->last_buffer] - [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = + [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) & 0xfffffff0) | 0x3); @@ -1073,7 +1073,7 @@ spin_unlock_irqrestore(&d->lock,flags); - if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) + if (!(reg_read(ohci, d->ctrlSet) & 0x8000)) { DBGMSG(ohci->host->id, "Starting iso transmit DMA ctx=%d", d->ctx); @@ -1089,8 +1089,8 @@ else { /* Wake up dma context if necessary */ if (!(reg_read(ohci, d->ctrlSet) & 0x400)) { - PRINT(KERN_INFO, ohci->host->id, - "Waking up iso transmit dma ctx=%d", + PRINT(KERN_INFO, ohci->host->id, + "Waking up iso transmit dma ctx=%d", d->ctx); put_timestamp(ohci, d, d->last_buffer); reg_write(ohci, d->ctrlSet, 0x1000); @@ -1101,7 +1101,7 @@ kfree(qv.packet_sizes); return 0; - + } case VIDEO1394_IOC_TALK_WAIT_BUFFER: { @@ -1114,7 +1114,7 @@ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); if ((v.buffer<0) || (v.buffer>d->num_desc)) { - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d out of range",v.buffer); return -EFAULT; } @@ -1131,7 +1131,7 @@ if (signal_pending(current)) return -EINTR; } #else - if (wait_event_interruptible(d->waitq, + if (wait_event_interruptible(d->waitq, d->buffer_status[v.buffer] == VIDEO1394_BUFFER_READY) == -ERESTARTSYS) @@ -1140,7 +1140,7 @@ d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE; return 0; default: - PRINT(KERN_ERR, ohci->host->id, + PRINT(KERN_ERR, ohci->host->id, "Buffer %d is not queued",v.buffer); return -EFAULT; } @@ -1153,7 +1153,7 @@ /* * This maps the vmalloced and reserved buffer to user space. * - * FIXME: + * FIXME: * - PAGE_READONLY should suffice!? * - remap_page_range is kind of inefficient for page by page remapping. * But e.g. pte_alloc() does not work in modules ... :-( @@ -1211,7 +1211,7 @@ struct dma_iso_ctx *d; d = list_entry(lh, struct dma_iso_ctx, link); mask = (u64) 1 << d->channel; - + if (!(ohci->ISO_channel_usage & mask)) PRINT(KERN_ERR, ohci->host->id, "On release: Channel %d " "is not being used", d->channel); @@ -1226,7 +1226,7 @@ kfree(ctx); file->private_data = NULL; - + unlock_kernel(); return 0; } @@ -1285,7 +1285,7 @@ hpsb_set_hostinfo(&video1394_highlevel, host, ohci); hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); - minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; + minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor), S_IFCHR | S_IRUSR | S_IWUSR, "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id); @@ -1438,7 +1438,7 @@ ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_TALK_WAIT_BUFFER); ret |= unregister_ioctl32_conversion(VIDEO1394_IOC32_LISTEN_POLL_BUFFER); if (ret) - PRINT_G(KERN_INFO, "Error unregistering ioctl32 translations"); + PRINT_G(KERN_CRIT, "Error unregistering ioctl32 translations"); #endif hpsb_unregister_protocol(&video1394_driver); @@ -1457,6 +1457,7 @@ cdev_init(&video1394_cdev, &video1394_fops); video1394_cdev.owner = THIS_MODULE; + kobject_set_name(&video1394_cdev.kobj, VIDEO1394_DRIVER_NAME); ret = cdev_add(&video1394_cdev, IEEE1394_VIDEO1394_DEV, 16); if (ret) { PRINT_G(KERN_ERR, "video1394: unable to get minor device block"); diff -Nru a/drivers/ieee1394/video1394.h b/drivers/ieee1394/video1394.h --- a/drivers/ieee1394/video1394.h Sun Apr 18 13:42:41 2004 +++ b/drivers/ieee1394/video1394.h Sun Apr 18 13:42:41 2004 @@ -42,7 +42,7 @@ unsigned int sync_tag; unsigned int nb_buffers; unsigned int buf_size; - unsigned int packet_size; /* For VARIABLE_PACKET_SIZE: + unsigned int packet_size; /* For VARIABLE_PACKET_SIZE: Maximum packet size */ unsigned int fps; unsigned int syt_offset; @@ -53,7 +53,7 @@ struct video1394_queue_variable { unsigned int channel; unsigned int buffer; - unsigned int* packet_sizes; /* Buffer of size: + unsigned int* packet_sizes; /* Buffer of size: buf_size / packet_size */ }; diff -Nru a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c --- a/drivers/isdn/capi/capi.c Sun Apr 18 13:42:41 2004 +++ b/drivers/isdn/capi/capi.c Sun Apr 18 13:42:41 2004 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,8 @@ /* -------- driver information -------------------------------------- */ +static struct class_simple *capi_class; + int capi_major = 68; /* allocated */ #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE #define CAPINC_NR_PORTS 32 @@ -1313,7 +1316,8 @@ drv->owner = THIS_MODULE; drv->driver_name = "capi_nc"; - drv->name = "capi/"; + drv->devfs_name = "capi/"; + drv->name = "capi"; drv->major = capi_ttymajor; drv->minor_start = 0; drv->type = TTY_DRIVER_TYPE_SERIAL; @@ -1483,11 +1487,20 @@ return -EIO; } + capi_class = class_simple_create(THIS_MODULE, "capi"); + if (IS_ERR(capi_class)) { + unregister_chrdev(capi_major, "capi20"); + return PTR_ERR(capi_class); + } + + class_simple_device_add(capi_class, MKDEV(capi_major, 0), NULL, "capi"); devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, "isdn/capi20"); #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE if (capinc_tty_init() < 0) { + class_simple_device_remove(MKDEV(capi_major, 0)); + class_simple_destroy(capi_class); unregister_chrdev(capi_major, "capi20"); return -ENOMEM; } @@ -1514,6 +1527,8 @@ { proc_exit(); + class_simple_device_remove(MKDEV(capi_major, 0)); + class_simple_destroy(capi_class); unregister_chrdev(capi_major, "capi20"); devfs_remove("isdn/capi20"); diff -Nru a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig --- a/drivers/isdn/i4l/Kconfig Sun Apr 18 13:42:40 2004 +++ b/drivers/isdn/i4l/Kconfig Sun Apr 18 13:42:40 2004 @@ -31,6 +31,17 @@ by bundling several ISDN-connections, using this protocol. See for more information. +config IPPP_FILTER + bool "Filtering for synchronous PPP" + depends on ISDN_PPP + help + Say Y here if you want to be able to filter the packets passing over + IPPP interfaces. This allows you to control which packets count as + activity (i.e. which packets will reset the idle timer or bring up + a demand-dialled link) and which packets are to be dropped entirely. + You need to say Y here if you wish to use the pass-filter and + active-filter options to ipppd. + config ISDN_PPP_BSDCOMP tristate "Support BSD compression" depends on ISDN_PPP diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c --- a/drivers/isdn/i4l/isdn_ppp.c Sun Apr 18 13:42:41 2004 +++ b/drivers/isdn/i4l/isdn_ppp.c Sun Apr 18 13:42:41 2004 @@ -606,7 +606,7 @@ if (copy_from_user(&uprog, (void *) arg, sizeof(uprog))) return -EFAULT; - if (uprog.len > 0 && uprog.len < 65536) { + if (uprog.len > 0) { len = uprog.len * sizeof(struct sock_filter); code = kmalloc(len, GFP_KERNEL); if (code == NULL) @@ -1121,7 +1121,12 @@ * the filter instructions are constructed assuming * a four-byte PPP header on each packet (which is still present) */ skb_push(skb, 4); - skb->data[0] = 0; /* indicate inbound */ + + { + u_int16_t *p = (u_int16_t *) skb->data; + + *p = 0; /* indicate inbound in DLT_LINUX_SLL */ + } if (is->pass_filter.filter && sk_run_filter(skb, is->pass_filter.filter, @@ -1263,8 +1268,13 @@ * the filter instructions are constructed assuming * a four-byte PPP header on each packet */ skb_push(skb, 4); - skb->data[0] = 1; /* indicate outbound */ - *(u_int16_t *)(skb->data + 2) = htons(proto); + + { + u_int16_t *p = (u_int16_t *) skb->data; + + *p++ = htons(4); /* indicate outbound in DLT_LINUX_SLL */ + *p = htons(proto); + } if (ipt->pass_filter.filter && sk_run_filter(skb, ipt->pass_filter.filter, @@ -1457,8 +1467,13 @@ * earlier. */ skb_pull(skb, IPPP_MAX_HEADER - 4); - skb->data[0] = 1; /* indicate outbound */ - *(u_int16_t *)(skb->data + 2) = htons(proto); + + { + u_int16_t *p = (u_int16_t *) skb->data; + + *p++ = htons(4); /* indicate outbound in DLT_LINUX_SLL */ + *p = htons(proto); + } drop |= is->pass_filter.filter && sk_run_filter(skb, is->pass_filter.filter, diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c --- a/drivers/md/dm-ioctl.c Sun Apr 18 13:42:40 2004 +++ b/drivers/md/dm-ioctl.c Sun Apr 18 13:42:40 2004 @@ -800,7 +800,7 @@ struct dm_target *ti = dm_table_get_target(table, i); remaining = len - (outptr - outbuf); - if (remaining < sizeof(struct dm_target_spec)) { + if (remaining <= sizeof(struct dm_target_spec)) { param->flags |= DM_BUFFER_FULL_FLAG; break; } @@ -815,6 +815,10 @@ outptr += sizeof(struct dm_target_spec); remaining = len - (outptr - outbuf); + if (remaining <= 0) { + param->flags |= DM_BUFFER_FULL_FLAG; + break; + } /* Get the status/table string from the target driver */ if (ti->type->status) { @@ -828,7 +832,7 @@ outptr += strlen(outptr) + 1; used = param->data_start + (outptr - outbuf); - align_ptr(outptr); + outptr = align_ptr(outptr); spec->next = outptr - outbuf; } diff -Nru a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c --- a/drivers/md/dm-stripe.c Sun Apr 18 13:42:41 2004 +++ b/drivers/md/dm-stripe.c Sun Apr 18 13:42:41 2004 @@ -187,24 +187,24 @@ status_type_t type, char *result, unsigned int maxlen) { struct stripe_c *sc = (struct stripe_c *) ti->private; - int offset; + unsigned int sz = 0; unsigned int i; char buffer[32]; +#define EMIT(x...) sz += ((sz >= maxlen) ? \ + 0 : scnprintf(result + sz, maxlen - sz, x)) + switch (type) { case STATUSTYPE_INFO: result[0] = '\0'; break; case STATUSTYPE_TABLE: - offset = scnprintf(result, maxlen, "%d " SECTOR_FORMAT, - sc->stripes, sc->chunk_mask + 1); + EMIT("%d " SECTOR_FORMAT, sc->stripes, sc->chunk_mask + 1); for (i = 0; i < sc->stripes; i++) { format_dev_t(buffer, sc->stripe[i].dev->bdev->bd_dev); - offset += - scnprintf(result + offset, maxlen - offset, - " %s " SECTOR_FORMAT, buffer, - sc->stripe[i].physical_start); + EMIT(" %s " SECTOR_FORMAT, buffer, + sc->stripe[i].physical_start); } break; } diff -Nru a/drivers/md/dm-table.c b/drivers/md/dm-table.c --- a/drivers/md/dm-table.c Sun Apr 18 13:42:41 2004 +++ b/drivers/md/dm-table.c Sun Apr 18 13:42:41 2004 @@ -663,12 +663,14 @@ if (!len) { tgt->error = "zero-length target"; + DMERR(": %s\n", tgt->error); return -EINVAL; } tgt->type = dm_get_target_type(type); if (!tgt->type) { tgt->error = "unknown target type"; + DMERR(": %s\n", tgt->error); return -EINVAL; } @@ -705,7 +707,7 @@ return 0; bad: - printk(KERN_ERR DM_NAME ": %s\n", tgt->error); + DMERR(": %s\n", tgt->error); dm_put_target_type(tgt->type); return r; } diff -Nru a/drivers/md/dm.c b/drivers/md/dm.c --- a/drivers/md/dm.c Sun Apr 18 13:42:41 2004 +++ b/drivers/md/dm.c Sun Apr 18 13:42:41 2004 @@ -294,6 +294,9 @@ if (bio->bi_size) return 1; + if (!bio_flagged(bio, BIO_UPTODATE) && !error) + error = -EIO; + if (endio) { r = endio(tio->ti, bio, error, &tio->info); if (r < 0) @@ -745,7 +748,7 @@ down_write(&md->lock); md->event_nr++; - wake_up_interruptible(&md->eventq); + wake_up(&md->eventq); up_write(&md->lock); } @@ -922,7 +925,7 @@ while (1) { set_current_state(TASK_INTERRUPTIBLE); - if (!atomic_read(&md->pending)) + if (!atomic_read(&md->pending) || signal_pending(current)) break; io_schedule(); @@ -931,6 +934,14 @@ down_write(&md->lock); remove_wait_queue(&md->wait, &wait); + + /* were we interrupted ? */ + if (atomic_read(&md->pending)) { + clear_bit(DMF_BLOCK_IO, &md->flags); + up_write(&md->lock); + return -EINTR; + } + set_bit(DMF_SUSPENDED, &md->flags); map = dm_get_table(md); diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c --- a/drivers/net/8390.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/8390.c Sun Apr 18 13:42:40 2004 @@ -1084,7 +1084,7 @@ for(i = 0; i < 6; i++) { outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); - if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) + if (ei_debug > 1 && inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) printk(KERN_ERR "Hw. address read/write mismap %d\n",i); } diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h --- a/drivers/net/8390.h Sun Apr 18 13:42:41 2004 +++ b/drivers/net/8390.h Sun Apr 18 13:42:41 2004 @@ -131,8 +131,19 @@ #define inb_p(port) in_8(port) #define outb_p(val,port) out_8(port,val) -#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) || \ - defined(CONFIG_NET_CBUS) +#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) +#define EI_SHIFT(x) (ei_local->reg_offset[x]) +#undef inb +#undef inb_p +#undef outb +#undef outb_p + +#define inb(_p) readb(_p) +#define outb(_v,_p) writeb(_v,_p) +#define inb_p(_p) inb(_p) +#define outb_p(_v,_p) outb(_v,_p) + +#elif defined(CONFIG_NET_CBUS) #define EI_SHIFT(x) (ei_local->reg_offset[x]) #else #define EI_SHIFT(x) (x) diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Sun Apr 18 13:42:41 2004 +++ b/drivers/net/Kconfig Sun Apr 18 13:42:41 2004 @@ -21,10 +21,6 @@ If unsure, say Y. -if NETDEVICES - source "drivers/net/arcnet/Kconfig" -endif - config DUMMY tristate "Dummy net driver support" depends on NETDEVICES @@ -155,6 +151,10 @@ If you don't have this card, of course say N. +if NETDEVICES + source "drivers/net/arcnet/Kconfig" +endif + # # Ethernet # @@ -1178,6 +1178,17 @@ boards with this driver should be possible, but has not been tested up to now due to lack of hardware. +config IBMVETH + tristate "IBM LAN Virtual Ethernet support" + depends on NETDEVICES && NET_ETHERNET && PPC_PSERIES + ---help--- + This driver supports virtual ethernet adapters on newer IBM iSeries + and pSeries systems. + + To compile this driver as a module, choose M here and read + . The module will + be called ibmveth. + config NET_PCI bool "EISA, VLB, PCI and on board controllers" depends on NET_ETHERNET && (ISA || EISA || PCI) @@ -1219,6 +1230,9 @@ To compile this driver as a module, choose M here and read . The module will be called amd8111e. +config AMD8111E_NAPI + bool "Enable NAPI support" + depends on AMD8111_ETH config ADAPTEC_STARFIRE tristate "Adaptec Starfire/DuraLAN support" @@ -2105,6 +2119,17 @@ endmenu +source "drivers/net/tokenring/Kconfig" + +source "drivers/net/wireless/Kconfig" + +source "drivers/net/pcmcia/Kconfig" + +source "drivers/net/wan/Kconfig" + +source "drivers/atm/Kconfig" + +source "drivers/s390/net/Kconfig" config ISERIES_VETH tristate "iSeries Virtual Ethernet driver support" @@ -2172,17 +2197,6 @@ under Linux, say Y here (you must also remember to enable the driver for your HIPPI card below). Most people will say N here. -config IBMVETH - tristate "IBM LAN Virtual Ethernet support" - depends on NETDEVICES && NET_ETHERNET && PPC_PSERIES - ---help--- - This driver supports virtual ethernet adapters on newer IBM iSeries - and pSeries systems. - - To compile this driver as a module, choose M here and read - . The module will - be called ibmveth. - config ROADRUNNER tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)" depends on HIPPI && PCI @@ -2440,10 +2454,6 @@ end of the link as well. It's good enough, for example, to run IP over the async ports of a Camtec JNT Pad. If unsure, say N. -source "drivers/net/wireless/Kconfig" - -source "drivers/net/tokenring/Kconfig" - config NET_FC bool "Fibre Channel driver support" depends on NETDEVICES && SCSI && PCI @@ -2503,11 +2513,3 @@ ---help--- If you want to log kernel messages over the network, enable this. See Documentation/networking/netconsole.txt for details. - -source "drivers/net/wan/Kconfig" - -source "drivers/net/pcmcia/Kconfig" - -source "drivers/atm/Kconfig" - -source "drivers/s390/net/Kconfig" diff -Nru a/drivers/net/a2065.c b/drivers/net/a2065.c --- a/drivers/net/a2065.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/a2065.c Sun Apr 18 13:42:41 2004 @@ -274,6 +274,7 @@ struct sk_buff *skb = 0; /* XXX shut up gcc warnings */ #ifdef TEST_HITS + int i; printk ("["); for (i = 0; i < RX_RING_SIZE; i++) { if (i == lp->rx_new) diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c --- a/drivers/net/amd8111e.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/amd8111e.c Sun Apr 18 13:42:41 2004 @@ -1,6 +1,6 @@ /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver - * Copyright (C) 2003 Advanced Micro Devices + * Copyright (C) 2004 Advanced Micro Devices * * * Copyright 2001,2002 Jeff Garzik [ 8139cp.c,tg3.c ] @@ -55,6 +55,16 @@ 4. Dynamic IPG support is disabled by default. 3.0.3 06/05/2003 1. Bug fix: Fixed failure to close the interface if SMP is enabled. + 3.0.4 12/09/2003 + 1. Added set_mac_address routine for bonding driver support. + 2. Tested the driver for bonding support + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth + indicated to the h/w. + 4. Modified amd8111e_rx() routine to receive all the received packets + in the first interrupt. + 5. Bug fix: Corrected rx_errors reported in get_stats() function. + 3.0.5 03/22/2004 + 1. Added NAPI support */ @@ -91,7 +101,7 @@ #include "amd8111e.h" #define MODULE_NAME "amd8111e" -#define MODULE_VERS "3.0.3" +#define MODULE_VERS "3.0.5" MODULE_AUTHOR("Advanced Micro Devices, Inc."); MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3"); MODULE_LICENSE("GPL"); @@ -276,8 +286,10 @@ unsigned int mtu = dev->mtu; if (mtu > ETH_DATA_LEN){ - /* MTU + ethernet header + FCS + optional VLAN tag */ - lp->rx_buff_len = mtu + ETH_HLEN + 8; + /* MTU + ethernet header + FCS + + optional VLAN tag + skb reserve space 2 */ + + lp->rx_buff_len = mtu + ETH_HLEN + 10; lp->options |= OPTION_JUMBO_ENABLE; } else{ lp->rx_buff_len = PKT_BUFF_SZ; @@ -337,7 +349,7 @@ lp->rx_skbuff[i]->data,lp->rx_buff_len-2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[i]); - lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len); + lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len-2); lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT); } @@ -513,6 +525,9 @@ void * mmio = lp->mmio; + /* stop the chip */ + writel(RUN, mmio + CMD0); + /* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */ writew( 0x8101, mmio + AUTOPOLL0); @@ -654,7 +669,11 @@ */ static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag) { +#ifdef CONFIG_AMD8111E_NAPI + return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag); +#else return vlan_hwaccel_rx(skb, lp->vlgrp, vlan_tag); +#endif /* CONFIG_AMD8111E_NAPI */ } #endif @@ -700,6 +719,142 @@ return 0; } +#if CONFIG_AMD8111E_NAPI +/* This function handles the driver receive operation in polling mode */ +static int amd8111e_rx_poll(struct net_device *dev, int * budget) +{ + struct amd8111e_priv *lp = dev->priv; + int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; + void * mmio = lp->mmio; + struct sk_buff *skb,*new_skb; + int min_pkt_len, status; + unsigned int intr0; + int num_rx_pkt = 0; + /*int max_rx_pkt = NUM_RX_BUFFERS;*/ + short pkt_len; +#if AMD8111E_VLAN_TAG_USED + short vtag; +#endif + int rx_pkt_limit = dev->quota; + + do{ + /* process receive packets until we use the quota*/ + /* If we own the next entry, it's a new packet. Send it up. */ + while(!(lp->rx_ring[rx_index].rx_flags & OWN_BIT)){ + + /* check if err summary bit is set */ + if(le16_to_cpu(lp->rx_ring[rx_index].rx_flags) + & ERR_BIT){ + /* + * There is a tricky error noted by John Murphy, + * to Russ Nelson: Even with + * full-sized * buffers it's possible for a + * jabber packet to use two buffers, with only + * the last correctly noting the error. + */ + + /* reseting flags */ + lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS; + goto err_next_pkt; + + } + /* check for STP and ENP */ + status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags); + if(!((status & STP_BIT) && (status & ENP_BIT))){ + /* reseting flags */ + lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS; + goto err_next_pkt; + } + pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4; + +#if AMD8111E_VLAN_TAG_USED + vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & TT_MASK; + /*MAC will strip vlan tag*/ + if(lp->vlgrp != NULL && vtag !=0) + min_pkt_len =MIN_PKT_LEN - 4; + else +#endif + min_pkt_len =MIN_PKT_LEN; + + if (pkt_len < min_pkt_len) { + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; + lp->drv_rx_errors++; + goto err_next_pkt; + } + if(--rx_pkt_limit < 0) + goto rx_not_empty; + if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ + /* if allocation fail, + ignore that pkt and go to next one */ + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; + lp->drv_rx_errors++; + goto err_next_pkt; + } + + skb_reserve(new_skb, 2); + skb = lp->rx_skbuff[rx_index]; + pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index], + lp->rx_buff_len-2, PCI_DMA_FROMDEVICE); + skb_put(skb, pkt_len); + skb->dev = dev; + lp->rx_skbuff[rx_index] = new_skb; + new_skb->dev = dev; + lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev, + new_skb->data, lp->rx_buff_len-2,PCI_DMA_FROMDEVICE); + + skb->protocol = eth_type_trans(skb, dev); + +#if AMD8111E_VLAN_TAG_USED + + vtag = lp->rx_ring[rx_index].rx_flags & TT_MASK; + if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){ + amd8111e_vlan_rx(lp, skb, + lp->rx_ring[rx_index].tag_ctrl_info); + } else +#endif + + netif_receive_skb(skb); + /*COAL update rx coalescing parameters*/ + lp->coal_conf.rx_packets++; + lp->coal_conf.rx_bytes += pkt_len; + num_rx_pkt++; + dev->last_rx = jiffies; + +err_next_pkt: + lp->rx_ring[rx_index].buff_phy_addr + = cpu_to_le32(lp->rx_dma_addr[rx_index]); + lp->rx_ring[rx_index].buff_count = + cpu_to_le16(lp->rx_buff_len-2); + lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT); + rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK; + } + /* Check the interrupt status register for more packets in the + mean time. Process them since we have not used up our quota.*/ + + intr0 = readl(mmio + INT0); + /*Ack receive packets */ + writel(intr0 & RINT0,mmio + INT0); + + }while(intr0 & RINT0); + + /* Receive descriptor is empty now */ + dev->quota -= num_rx_pkt; + *budget -= num_rx_pkt; + netif_rx_complete(dev); + /* enable receive interrupt */ + writel(VAL0|RINTEN0, mmio + INTEN0); + writel(VAL2 | RDMD0, mmio + CMD0); + return 0; +rx_not_empty: + /* Do not call a netif_rx_complete */ + dev->quota -= num_rx_pkt; + *budget -= num_rx_pkt; + return 1; + + +} + +#else /* This function will check the ownership of receive buffers and descriptors. It will indicate to kernel up to half the number of maximum receive buffers in the descriptor ring, in a single receive interrupt. It will also replenish the descriptors with new skbs. */ @@ -710,7 +865,7 @@ int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; int min_pkt_len, status; int num_rx_pkt = 0; - int max_rx_pkt = NUM_RX_BUFFERS/2; + int max_rx_pkt = NUM_RX_BUFFERS; short pkt_len; #if AMD8111E_VLAN_TAG_USED short vtag; @@ -752,14 +907,14 @@ if (pkt_len < min_pkt_len) { lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; - lp->stats.rx_errors++; + lp->drv_rx_errors++; goto err_next_pkt; } if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ /* if allocation fail, ignore that pkt and go to next one */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; - lp->stats.rx_errors++; + lp->drv_rx_errors++; goto err_next_pkt; } @@ -803,7 +958,7 @@ return 0; } - +#endif /* CONFIG_AMD8111E_NAPI */ /* This function will indicate the link status to the kernel. */ @@ -896,12 +1051,14 @@ new_stats->tx_bytes = amd8111e_read_mib(mmio, xmt_octets); /* stats.rx_errors */ + /* hw errors + errors driver reported */ new_stats->rx_errors = amd8111e_read_mib(mmio, rcv_undersize_pkts)+ amd8111e_read_mib(mmio, rcv_fragments)+ amd8111e_read_mib(mmio, rcv_jabbers)+ amd8111e_read_mib(mmio, rcv_alignment_errors)+ amd8111e_read_mib(mmio, rcv_fcs_errors)+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + amd8111e_read_mib(mmio, rcv_miss_pkts)+ + lp->drv_rx_errors; /* stats.tx_errors */ new_stats->tx_errors = amd8111e_read_mib(mmio, xmt_underrun_pkts); @@ -1119,20 +1276,36 @@ /* Process all the INT event until INTR bit is clear. */ - if (!(intr0 & INTR)) { + if (!(intr0 & INTR)){ handled = 0; goto err_no_interrupt; } - /* Current driver processes 3 interrupts : RINT,TINT,LCINT */ + /* Current driver processes 4 interrupts : RINT,TINT,LCINT,STINT */ writel(intr0, mmio + INT0); /* Check if Receive Interrupt has occurred. */ +#if CONFIG_AMD8111E_NAPI + if(intr0 & RINT0){ + if(netif_rx_schedule_prep(dev)){ + /* Disable receive interupts */ + writel(RINTEN0, mmio + INTEN0); + /* Schedule a polling routine */ + __netif_rx_schedule(dev); + } + else { + printk("************Driver bug! \ + interrupt while in poll\n"); + /* Fix by disabling interrupts */ + writel(RINT0, mmio + INT0); + } + } +#else if(intr0 & RINT0){ amd8111e_rx(dev); writel(VAL2 | RDMD0, mmio + CMD0); } - +#endif /* CONFIG_AMD8111E_NAPI */ /* Check if Transmit Interrupt has occurred. */ if(intr0 & TINT0) amd8111e_tx(dev); @@ -1164,6 +1337,7 @@ } #endif + /* This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down. */ @@ -1186,7 +1360,7 @@ spin_unlock_irq(&lp->lock); free_irq(dev->irq, dev); - + /* Update the statistics before closing */ amd8111e_get_stats(dev); lp->opened = 0; @@ -1560,6 +1734,23 @@ } return -EOPNOTSUPP; } +static int amd8111e_set_mac_address(struct net_device *dev, void *p) +{ + struct amd8111e_priv *lp = dev->priv; + int i; + struct sockaddr *addr = p; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + spin_lock_irq(&lp->lock); + /* Setting the MAC address to the device */ + for(i = 0; i < ETH_ADDR_LEN; i++) + writeb( dev->dev_addr[i], lp->mmio + PADR + i ); + + spin_unlock_irq(&lp->lock); + + return 0; +} + /* This function changes the mtu of the device. It restarts the device to initialize the descriptor with new receive buffers. */ @@ -1890,11 +2081,16 @@ dev->stop = amd8111e_close; dev->get_stats = amd8111e_get_stats; dev->set_multicast_list = amd8111e_set_multicast_list; + dev->set_mac_address = amd8111e_set_mac_address; dev->do_ioctl = amd8111e_ioctl; dev->change_mtu = amd8111e_change_mtu; dev->irq =pdev->irq; dev->tx_timeout = amd8111e_tx_timeout; dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; +#ifdef CONFIG_AMD8111E_NAPI + dev->poll = amd8111e_rx_poll; + dev->weight = 32; +#endif #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = amd8111e_poll; #endif @@ -1908,6 +2104,7 @@ /* Set receive buffer length and set jumbo option*/ amd8111e_set_rx_buff_len(dev); + err = register_netdev(dev); if (err) { printk(KERN_ERR "amd8111e: Cannot register net device, " @@ -1954,7 +2151,7 @@ } static struct pci_driver amd8111e_driver = { - .name = MODULE_NAME, + .name = MODULE_NAME, .id_table = amd8111e_pci_tbl, .probe = amd8111e_probe_one, .remove = __devexit_p(amd8111e_remove_one), diff -Nru a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h --- a/drivers/net/amd8111e.h Sun Apr 18 13:42:40 2004 +++ b/drivers/net/amd8111e.h Sun Apr 18 13:42:40 2004 @@ -606,7 +606,7 @@ /* ipg parameters */ #define DEFAULT_IPG 0x60 #define IFS1_DELTA 36 -#define IPG_CONVERGE_JIFFIES (HZ / 2) +#define IPG_CONVERGE_JIFFIES (HZ/2) #define IPG_STABLE_TIME 5 #define MIN_IPG 96 #define MAX_IPG 255 @@ -790,6 +790,7 @@ #endif char opened; struct net_device_stats stats; + unsigned int drv_rx_errors; struct dev_mc_list* mc_list; struct amd8111e_coalesce_conf coal_conf; diff -Nru a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c --- a/drivers/net/arcnet/com20020-isa.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/arcnet/com20020-isa.c Sun Apr 18 13:42:40 2004 @@ -185,8 +185,6 @@ #ifndef MODULE static int __init com20020isa_setup(char *s) { - struct net_device *dev; - struct arcnet_local *lp; int ints[8]; s = get_options(s, 8, ints); diff -Nru a/drivers/net/ariadne.c b/drivers/net/ariadne.c --- a/drivers/net/ariadne.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/ariadne.c Sun Apr 18 13:42:41 2004 @@ -216,7 +216,7 @@ } zorro_set_drvdata(z, dev); - printk("%s: Ariadne at 0x%08lx, Ethernet Address " + printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address " "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); @@ -245,16 +245,16 @@ lance->RAP = CSR89; /* Chip ID */ version |= swapw(lance->RDP)<<16; if ((version & 0x00000fff) != 0x00000003) { - printk("ariadne_open: Couldn't find AMD Ethernet Chip\n"); + printk(KERN_WARNING "ariadne_open: Couldn't find AMD Ethernet Chip\n"); return -EAGAIN; } if ((version & 0x0ffff000) != 0x00003000) { - printk("ariadne_open: Couldn't find Am79C960 (Wrong part number = %ld)\n", - (version & 0x0ffff000)>>12); + printk(KERN_WARNING "ariadne_open: Couldn't find Am79C960 (Wrong part " + "number = %ld)\n", (version & 0x0ffff000)>>12); return -EAGAIN; } #if 0 - printk("ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n", + printk(KERN_DEBUG "ariadne_open: Am79C960 (PCnet-ISA) Revision %ld\n", (version & 0xf0000000)>>28); #endif @@ -354,8 +354,8 @@ priv->tx_ring[i] = &lancedata->tx_ring[i]; priv->tx_buff[i] = lancedata->tx_buff[i]; #if 0 - printk("TX Entry %2d at %p, Buf at %p\n", i, &lancedata->tx_ring[i], - lancedata->tx_buff[i]); + printk(KERN_DEBUG "TX Entry %2d at %p, Buf at %p\n", i, + &lancedata->tx_ring[i], lancedata->tx_buff[i]); #endif } @@ -370,8 +370,8 @@ priv->rx_ring[i] = &lancedata->rx_ring[i]; priv->rx_buff[i] = lancedata->rx_buff[i]; #if 0 - printk("RX Entry %2d at %p, Buf at %p\n", i, &lancedata->rx_ring[i], - lancedata->rx_buff[i]); + printk(KERN_DEBUG "RX Entry %2d at %p, Buf at %p\n", i, + &lancedata->rx_ring[i], lancedata->rx_buff[i]); #endif } } @@ -389,9 +389,9 @@ lance->RAP = CSR0; /* PCnet-ISA Controller Status */ if (ariadne_debug > 1) { - printk("%s: Shutting down ethercard, status was %2.2x.\n", dev->name, - lance->RDP); - printk("%s: %lu packets missed\n", dev->name, + printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", + dev->name, lance->RDP); + printk(KERN_DEBUG "%s: %lu packets missed\n", dev->name, priv->stats.rx_missed_errors); } @@ -425,7 +425,7 @@ int handled = 0; if (dev == NULL) { - printk("ariadne_interrupt(): irq for unknown device.\n"); + printk(KERN_WARNING "ariadne_interrupt(): irq for unknown device.\n"); return IRQ_NONE; } @@ -443,8 +443,8 @@ #if 0 if (ariadne_debug > 5) { - printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.", dev->name, - csr0, lance->RDP); + printk(KERN_DEBUG "%s: interrupt csr0=%#2.2x new csr=%#2.2x.", + dev->name, csr0, lance->RDP); printk("["); if (csr0 & INTR) printk(" INTR"); @@ -514,8 +514,8 @@ /* Ackk! On FIFO errors the Tx unit is turned off! */ priv->stats.tx_fifo_errors++; /* Remove this verbosity later! */ - printk("%s: Tx FIFO error! Status %4.4x.\n", dev->name, - csr0); + printk(KERN_ERR "%s: Tx FIFO error! Status %4.4x.\n", + dev->name, csr0); /* Restart the chip. */ lance->RDP = STRT; } @@ -529,8 +529,8 @@ #ifndef final_version if (priv->cur_tx - dirty_tx >= TX_RING_SIZE) { - printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n", - dirty_tx, priv->cur_tx, priv->tx_full); + printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d, " + "full=%d.\n", dirty_tx, priv->cur_tx, priv->tx_full); dirty_tx += TX_RING_SIZE; } #endif @@ -556,8 +556,8 @@ } if (csr0 & MERR) { handled = 1; - printk("%s: Bus master arbitration failure, status %4.4x.\n", - dev->name, csr0); + printk(KERN_ERR "%s: Bus master arbitration failure, status " + "%4.4x.\n", dev->name, csr0); /* Restart the chip. */ lance->RDP = STRT; } @@ -569,8 +569,8 @@ #if 0 if (ariadne_debug > 4) - printk("%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, lance->RAP, - lance->RDP); + printk(KERN_DEBUG "%s: exiting interrupt, csr%d=%#4.4x.\n", dev->name, + lance->RAP, lance->RDP); #endif return IRQ_RETVAL(handled); } @@ -598,8 +598,8 @@ #if 0 if (ariadne_debug > 3) { lance->RAP = CSR0; /* PCnet-ISA Controller Status */ - printk("%s: ariadne_start_xmit() called, csr0 %4.4x.\n", dev->name, - lance->RDP); + printk(KERN_DEBUG "%s: ariadne_start_xmit() called, csr0 %4.4x.\n", + dev->name, lance->RDP); lance->RDP = 0x0000; } #endif @@ -616,7 +616,7 @@ /* Fill in a Tx ring entry */ #if 0 - printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); + printk(KERN_DEBUG "TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); { int i; u_char *ptr = &((u_char *)skb->data)[6]; @@ -652,7 +652,7 @@ len >>= 1; for (i = 0; i < len; i += 8) { int j; - printk("%04x:", i); + printk(KERN_DEBUG "%04x:", i); for (j = 0; (j < 8) && ((i+j) < len); j++) { if (!(j & 1)) printk(" "); @@ -671,8 +671,8 @@ if ((priv->cur_tx >= TX_RING_SIZE) && (priv->dirty_tx >= TX_RING_SIZE)) { #if 0 - printk("*** Subtracting TX_RING_SIZE from cur_tx (%d) and dirty_tx (%d)\n", - priv->cur_tx, priv->dirty_tx); + printk(KERN_DEBUG "*** Subtracting TX_RING_SIZE from cur_tx (%d) and " + "dirty_tx (%d)\n", priv->cur_tx, priv->dirty_tx); #endif priv->cur_tx -= TX_RING_SIZE; @@ -729,7 +729,8 @@ skb = dev_alloc_skb(pkt_len+2); if (skb == NULL) { - printk("%s: Memory squeeze, deferring packet.\n", dev->name); + printk(KERN_WARNING "%s: Memory squeeze, deferring packet.\n", + dev->name); for (i = 0; i < RX_RING_SIZE; i++) if (lowb(priv->rx_ring[(entry+i) % RX_RING_SIZE]->RMD1) & RF_OWN) break; @@ -749,7 +750,8 @@ eth_copy_and_sum(skb, (char *)priv->rx_buff[entry], pkt_len,0); skb->protocol=eth_type_trans(skb,dev); #if 0 - printk("RX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); + printk(KERN_DEBUG "RX pkt type 0x%04x from ", + ((u_short *)skb->data)[6]); { int i; u_char *ptr = &((u_char *)skb->data)[6]; @@ -825,7 +827,7 @@ if (dev->flags & IFF_PROMISC) { /* Log any net taps. */ - printk("%s: Promiscuous mode enabled.\n", dev->name); + printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); lance->RAP = CSR15; /* Mode Register */ lance->RDP = PROM; /* Set promiscuous mode */ } else { diff -Nru a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c --- a/drivers/net/arm/etherh.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/arm/etherh.c Sun Apr 18 13:42:41 2004 @@ -60,11 +60,28 @@ struct etherh_priv { struct ei_device eidev; + void *ioc_fast; + void *memc; unsigned int id; - unsigned int ctrl_port; + void *ctrl_port; unsigned int ctrl; }; +struct etherh_data { + unsigned long ns8390_offset; + unsigned long dataport_offset; + unsigned long ctrlport_offset; + int ctrl_ioc; + const char name[16]; + /* + * netdev flags and port + */ + unsigned short flags; + unsigned char if_port; + unsigned char tx_start_page; + unsigned char stop_page; +}; + MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("EtherH/EtherM driver"); MODULE_LICENSE("GPL"); @@ -72,13 +89,13 @@ static char version[] __initdata = "EtherH/EtherM Driver (c) 2002 Russell King v1.09\n"; -#define ETHERH500_DATAPORT 0x200 /* MEMC */ +#define ETHERH500_DATAPORT 0x800 /* MEMC */ #define ETHERH500_NS8390 0x000 /* MEMC */ -#define ETHERH500_CTRLPORT 0x200 /* IOC */ +#define ETHERH500_CTRLPORT 0x800 /* IOC */ -#define ETHERH600_DATAPORT 16 /* MEMC */ -#define ETHERH600_NS8390 0x200 /* MEMC */ -#define ETHERH600_CTRLPORT 0x080 /* MEMC */ +#define ETHERH600_DATAPORT 0x040 /* MEMC */ +#define ETHERH600_NS8390 0x800 /* MEMC */ +#define ETHERH600_CTRLPORT 0x200 /* MEMC */ #define ETHERH_CP_IE 1 #define ETHERH_CP_IF 2 @@ -90,9 +107,9 @@ /* * These came from CK/TEW */ -#define ETHERM_DATAPORT 0x080 /* MEMC */ -#define ETHERM_NS8390 0x200 /* MEMC */ -#define ETHERM_CTRLPORT 0x08f /* MEMC */ +#define ETHERM_DATAPORT 0x200 /* MEMC */ +#define ETHERM_NS8390 0x800 /* MEMC */ +#define ETHERM_CTRLPORT 0x23c /* MEMC */ #define ETHERM_TX_START_PAGE 64 #define ETHERM_STOP_PAGE 127 @@ -102,18 +119,18 @@ static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned int mask) { eh->ctrl |= mask; - outb(eh->ctrl, eh->ctrl_port); + writeb(eh->ctrl, eh->ctrl_port); } static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned int mask) { eh->ctrl &= ~mask; - outb(eh->ctrl, eh->ctrl_port); + writeb(eh->ctrl, eh->ctrl_port); } static inline unsigned int etherh_get_stat(struct etherh_priv *eh) { - return inb(eh->ctrl_port); + return readb(eh->ctrl_port); } @@ -158,10 +175,10 @@ switch (dev->if_port) { case IF_PORT_10BASE2: - outb((inb(addr) & 0xf8) | 1, addr); + writeb((readb(addr) & 0xf8) | 1, addr); break; case IF_PORT_10BASET: - outb((inb(addr) & 0xf8), addr); + writeb((readb(addr) & 0xf8), addr); break; } break; @@ -200,7 +217,7 @@ stat = 1; break; case IF_PORT_10BASET: - stat = inb(dev->base_addr+EN0_RCNTHI) & 4; + stat = readb(dev->base_addr+EN0_RCNTHI) & 4; break; } break; @@ -258,7 +275,7 @@ { struct ei_device *ei_local = netdev_priv(dev); - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); + writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); /* * See if we need to change the interface type. @@ -306,31 +323,31 @@ dma_addr = dev->mem_start; count = (count + 1) & ~1; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (0x42, addr + EN0_RCNTLO); - outb (0x00, addr + EN0_RCNTHI); - outb (0x42, addr + EN0_RSARLO); - outb (0x00, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (0x42, addr + EN0_RCNTLO); + writeb (0x00, addr + EN0_RCNTHI); + writeb (0x42, addr + EN0_RSARLO); + writeb (0x00, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); udelay (1); - outb (ENISR_RDC, addr + EN0_ISR); - outb (count, addr + EN0_RCNTLO); - outb (count >> 8, addr + EN0_RCNTHI); - outb (0, addr + EN0_RSARLO); - outb (start_page, addr + EN0_RSARHI); - outb (E8390_RWRITE | E8390_START, addr + E8390_CMD); + writeb (ENISR_RDC, addr + EN0_ISR); + writeb (count, addr + EN0_RCNTLO); + writeb (count >> 8, addr + EN0_RCNTHI); + writeb (0, addr + EN0_RSARLO); + writeb (start_page, addr + EN0_RSARHI); + writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD); if (ei_local->word16) - outsw (dma_addr, buf, count >> 1); + writesw (dma_addr, buf, count >> 1); else - outsb (dma_addr, buf, count); + writesb (dma_addr, buf, count); dma_start = jiffies; - while ((inb (addr + EN0_ISR) & ENISR_RDC) == 0) + while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for TX RDC\n", dev->name); @@ -339,7 +356,7 @@ break; } - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -366,21 +383,21 @@ dma_addr = dev->mem_start; buf = skb->data; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (count, addr + EN0_RCNTLO); - outb (count >> 8, addr + EN0_RCNTHI); - outb (ring_offset, addr + EN0_RSARLO); - outb (ring_offset >> 8, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (count, addr + EN0_RCNTLO); + writeb (count >> 8, addr + EN0_RCNTHI); + writeb (ring_offset, addr + EN0_RSARLO); + writeb (ring_offset >> 8, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); if (ei_local->word16) { - insw (dma_addr, buf, count >> 1); + readsw (dma_addr, buf, count >> 1); if (count & 1) - buf[count - 1] = inb (dma_addr); + buf[count - 1] = readb (dma_addr); } else - insb (dma_addr, buf, count); + readsb (dma_addr, buf, count); - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -405,19 +422,19 @@ addr = dev->base_addr; dma_addr = dev->mem_start; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (sizeof (*hdr), addr + EN0_RCNTLO); - outb (0, addr + EN0_RCNTHI); - outb (0, addr + EN0_RSARLO); - outb (ring_page, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (sizeof (*hdr), addr + EN0_RCNTLO); + writeb (0, addr + EN0_RCNTHI); + writeb (0, addr + EN0_RSARLO); + writeb (ring_page, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); if (ei_local->word16) - insw (dma_addr, hdr, sizeof (*hdr) >> 1); + readsw (dma_addr, hdr, sizeof (*hdr) >> 1); else - insb (dma_addr, hdr, sizeof (*hdr)); + readsb (dma_addr, hdr, sizeof (*hdr)); - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -543,18 +560,22 @@ static int __init etherh_probe(struct expansion_card *ec, const struct ecard_id *id) { + const struct etherh_data *data = id->data; struct ei_device *ei_local; struct net_device *dev; struct etherh_priv *eh; - const char *dev_type; - int i, size, ret; + int i, ret; etherh_banner(); + ret = ecard_request_resources(ec); + if (ret) + goto out; + dev = alloc_ei_netdev(); if (!dev) { ret = -ENOMEM; - goto out; + goto release; } eh = netdev_priv(dev); @@ -562,111 +583,64 @@ spin_lock_init(&eh->eidev.page_lock); SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &ec->dev); dev->open = etherh_open; dev->stop = etherh_close; dev->set_config = etherh_set_config; dev->irq = ec->irq; - dev->base_addr = ecard_address(ec, ECARD_MEMC, 0); + dev->if_port = data->if_port; + dev->flags |= data->flags; - /* - * IRQ and control port handling - */ - if (ec->irq != 11) { - ec->ops = ðerh_ops; - ec->irq_data = eh; - } eh->ctrl = 0; eh->id = ec->cid.product; - - switch (ec->cid.product) { - case PROD_ANT_ETHERM: - etherm_addr(dev->dev_addr); - dev->base_addr += ETHERM_NS8390; - dev->mem_start = dev->base_addr + ETHERM_DATAPORT; - eh->ctrl_port = dev->base_addr + ETHERM_CTRLPORT; - break; - - case PROD_I3_ETHERLAN500: - etherh_addr(dev->dev_addr, ec); - dev->base_addr += ETHERH500_NS8390; - dev->mem_start = dev->base_addr + ETHERH500_DATAPORT; - eh->ctrl_port = ecard_address (ec, ECARD_IOC, ECARD_FAST) - + ETHERH500_CTRLPORT; - break; - - case PROD_I3_ETHERLAN600: - case PROD_I3_ETHERLAN600A: - etherh_addr(dev->dev_addr, ec); - dev->base_addr += ETHERH600_NS8390; - dev->mem_start = dev->base_addr + ETHERH600_DATAPORT; - eh->ctrl_port = dev->base_addr + ETHERH600_CTRLPORT; - break; - - default: - printk(KERN_ERR "%s: unknown card type %x\n", - dev->name, ec->cid.product); - ret = -ENODEV; + eh->memc = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), PAGE_SIZE); + if (!eh->memc) { + ret = -ENOMEM; goto free; } - size = 16; - if (ec->cid.product == PROD_ANT_ETHERM) - size <<= 3; - - if (!request_region(dev->base_addr, size, dev->name)) { - ret = -EBUSY; - goto free; + eh->ctrl_port = eh->memc; + if (data->ctrl_ioc) { + eh->ioc_fast = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), PAGE_SIZE); + if (!eh->ioc_fast) { + ret = -ENOMEM; + goto free; + } + eh->ctrl_port = eh->ioc_fast; } + dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; + dev->mem_start = (unsigned long)eh->memc + data->dataport_offset; + eh->ctrl_port += data->ctrlport_offset; + /* - * If we're in the NIC slot, make sure the IRQ is enabled + * IRQ and control port handling - only for non-NIC slot cards. */ - if (dev->irq == 11) + if (ec->slot_no != 8) { + ec->ops = ðerh_ops; + ec->irq_data = eh; + } else { + /* + * If we're in the NIC slot, make sure the IRQ is enabled + */ etherh_set_ctrl(eh, ETHERH_CP_IE); - - switch (ec->cid.product) { - case PROD_ANT_ETHERM: - dev_type = "ANT EtherM"; - dev->if_port = IF_PORT_UNKNOWN; - break; - - case PROD_I3_ETHERLAN500: - dev_type = "i3 EtherH 500"; - dev->if_port = IF_PORT_UNKNOWN; - break; - - case PROD_I3_ETHERLAN600: - dev_type = "i3 EtherH 600"; - dev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; - dev->if_port = IF_PORT_10BASET; - break; - - case PROD_I3_ETHERLAN600A: - dev_type = "i3 EtherH 600A"; - dev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; - dev->if_port = IF_PORT_10BASET; - break; - - default: - dev_type = "unknown"; - break; } - ei_local = netdev_priv(dev); + ei_local = &eh->eidev; if (ec->cid.product == PROD_ANT_ETHERM) { - ei_local->tx_start_page = ETHERM_TX_START_PAGE; - ei_local->stop_page = ETHERM_STOP_PAGE; - ei_local->reg_offset = etherm_regoffsets; + etherm_addr(dev->dev_addr); + ei_local->reg_offset = etherm_regoffsets; } else { - ei_local->tx_start_page = ETHERH_TX_START_PAGE; - ei_local->stop_page = ETHERH_STOP_PAGE; - ei_local->reg_offset = etherh_regoffsets; + etherh_addr(dev->dev_addr, ec); + ei_local->reg_offset = etherh_regoffsets; } ei_local->name = dev->name; ei_local->word16 = 1; + ei_local->tx_start_page = data->tx_start_page; ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES; + ei_local->stop_page = data->stop_page; ei_local->reset_8390 = etherh_reset; ei_local->block_input = etherh_block_input; ei_local->block_output = etherh_block_output; @@ -678,10 +652,10 @@ ret = register_netdev(dev); if (ret) - goto release; + goto free; printk(KERN_INFO "%s: %s in slot %d, ", - dev->name, dev_type, ec->slot_no); + dev->name, data->name, ec->slot_no); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); @@ -690,10 +664,14 @@ return 0; - release: - release_region(dev->base_addr, 16); free: + if (eh->ioc_fast) + iounmap(eh->ioc_fast); + if (eh->memc) + iounmap(eh->memc); free_netdev(dev); + release: + ecard_release_resources(ec); out: return ret; } @@ -701,25 +679,69 @@ static void __devexit etherh_remove(struct expansion_card *ec) { struct net_device *dev = ecard_get_drvdata(ec); - int size = 16; + struct etherh_priv *eh = netdev_priv(dev); ecard_set_drvdata(ec, NULL); unregister_netdev(dev); - if (ec->cid.product == PROD_ANT_ETHERM) - size <<= 3; - release_region(dev->base_addr, size); + if (eh->ioc_fast) + iounmap(eh->ioc_fast); + iounmap(eh->memc); free_netdev(dev); ec->ops = NULL; kfree(ec->irq_data); + ecard_release_resources(ec); } +static struct etherh_data etherm_data = { + .ns8390_offset = ETHERM_NS8390, + .dataport_offset = ETHERM_NS8390 + ETHERM_DATAPORT, + .ctrlport_offset = ETHERM_NS8390 + ETHERM_CTRLPORT, + .name = "ANT EtherM", + .if_port = IF_PORT_UNKNOWN, + .tx_start_page = ETHERM_TX_START_PAGE, + .stop_page = ETHERM_STOP_PAGE, +}; + +static struct etherh_data etherlan500_data = { + .ns8390_offset = ETHERH500_NS8390, + .dataport_offset = ETHERH500_NS8390 + ETHERH500_DATAPORT, + .ctrlport_offset = ETHERH500_CTRLPORT, + .ctrl_ioc = 1, + .name = "i3 EtherH 500", + .if_port = IF_PORT_UNKNOWN, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + +static struct etherh_data etherlan600_data = { + .ns8390_offset = ETHERH600_NS8390, + .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, + .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, + .name = "i3 EtherH 600", + .flags = IFF_PORTSEL | IFF_AUTOMEDIA, + .if_port = IF_PORT_10BASET, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + +static struct etherh_data etherlan600a_data = { + .ns8390_offset = ETHERH600_NS8390, + .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, + .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, + .name = "i3 EtherH 600A", + .flags = IFF_PORTSEL | IFF_AUTOMEDIA, + .if_port = IF_PORT_10BASET, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + static const struct ecard_id etherh_ids[] = { - { MANU_ANT, PROD_ANT_ETHERM }, - { MANU_I3, PROD_I3_ETHERLAN500 }, - { MANU_I3, PROD_I3_ETHERLAN600 }, - { MANU_I3, PROD_I3_ETHERLAN600A }, + { MANU_ANT, PROD_ANT_ETHERM, ðerm_data }, + { MANU_I3, PROD_I3_ETHERLAN500, ðerlan500_data }, + { MANU_I3, PROD_I3_ETHERLAN600, ðerlan600_data }, + { MANU_I3, PROD_I3_ETHERLAN600A, ðerlan600a_data }, { 0xffff, 0xffff } }; @@ -737,8 +759,8 @@ int i; for (i = 0; i < 16; i++) { - etherh_regoffsets[i] = i; - etherm_regoffsets[i] = i << 3; + etherh_regoffsets[i] = i << 2; + etherm_regoffsets[i] = i << 5; } return ecard_register_driver(ðerh_driver); diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c --- a/drivers/net/b44.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/b44.c Sun Apr 18 13:42:41 2004 @@ -1382,7 +1382,7 @@ spin_unlock_irq(&bp->lock); } -static int b44_ethtool_ioctl (struct net_device *dev, void *useraddr) +static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr) { struct b44 *bp = dev->priv; struct pci_dev *pci_dev = bp->pdev; @@ -1625,13 +1625,13 @@ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; + struct mii_ioctl_data __user *data = (struct mii_ioctl_data __user *)&ifr->ifr_data; struct b44 *bp = dev->priv; int err; switch (cmd) { case SIOCETHTOOL: - return b44_ethtool_ioctl(dev, (void *) ifr->ifr_data); + return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data); case SIOCGMIIPHY: data->phy_id = bp->phy_addr; diff -Nru a/drivers/net/dummy.c b/drivers/net/dummy.c --- a/drivers/net/dummy.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/dummy.c Sun Apr 18 13:42:41 2004 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,17 @@ static int dummy_xmit(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *dummy_get_stats(struct net_device *dev); +static int dummy_set_address(struct net_device *dev, void *p) +{ + struct sockaddr *sa = p; + + if (!is_valid_ether_addr(sa->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); + return 0; +} + /* fake multicast ability */ static void set_multicast_list(struct net_device *dev) { @@ -58,6 +70,7 @@ dev->get_stats = dummy_get_stats; dev->hard_start_xmit = dummy_xmit; dev->set_multicast_list = set_multicast_list; + dev->set_mac_address = dummy_set_address; #ifdef CONFIG_NET_FASTROUTE dev->accept_fastpath = dummy_accept_fastpath; #endif @@ -68,6 +81,7 @@ dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; SET_MODULE_OWNER(dev); + random_ether_addr(dev->dev_addr); } static int dummy_xmit(struct sk_buff *skb, struct net_device *dev) @@ -90,6 +104,7 @@ /* Number of dummy devices to be set up by this module. */ module_param(numdummies, int, 0); +MODULE_PARM_DESC(numdimmies, "Number of dummy psuedo devices"); static int __init dummy_init_one(int index) { diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h --- a/drivers/net/e1000/e1000.h Sun Apr 18 13:42:40 2004 +++ b/drivers/net/e1000/e1000.h Sun Apr 18 13:42:40 2004 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -74,8 +75,6 @@ #define BAR_0 0 #define BAR_1 1 #define BAR_5 5 -#define PCI_DMA_64BIT 0xffffffffffffffffULL -#define PCI_DMA_32BIT 0x00000000ffffffffULL struct e1000_adapter; diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c --- a/drivers/net/e1000/e1000_main.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/e1000/e1000_main.c Sun Apr 18 13:42:40 2004 @@ -390,10 +390,10 @@ if((err = pci_enable_device(pdev))) return err; - if(!(err = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) { + if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { pci_using_dac = 1; } else { - if((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) { + if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { E1000_ERR("No usable DMA configuration, aborting\n"); return err; } diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c --- a/drivers/net/fc/iph5526.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/fc/iph5526.c Sun Apr 18 13:42:40 2004 @@ -2910,7 +2910,7 @@ { struct fc_info *fi = dev->priv; printk(KERN_WARNING "%s: timed out on send.\n", dev->name); - fi->fc_stats.rx_dropped++; + fi->fc_stats.tx_dropped++; dev->trans_start = jiffies; netif_wake_queue(dev); } @@ -2953,7 +2953,7 @@ fi->fc_stats.tx_packets++; } else - fi->fc_stats.rx_dropped++; + fi->fc_stats.tx_dropped++; dev->trans_start = jiffies; /* We free up the IP buffers in the OCI_interrupt handler. * status == 0 implies that the frame was not transmitted. So the diff -Nru a/drivers/net/hydra.c b/drivers/net/hydra.c --- a/drivers/net/hydra.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/hydra.c Sun Apr 18 13:42:41 2004 @@ -153,10 +153,11 @@ zorro_set_drvdata(z, dev); - printk("%s: Hydra at 0x%08lx, address %02x:%02x:%02x:%02x:%02x:%02x " - "(hydra.c " HYDRA_VERSION ")\n", dev->name, z->resource.start, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + printk(KERN_INFO "%s: Hydra at 0x%08lx, address " + "%02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n", + dev->name, z->resource.start, dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], + dev->dev_addr[5]); return 0; } @@ -170,14 +171,14 @@ static int hydra_close(struct net_device *dev) { if (ei_debug > 1) - printk("%s: Shutting down ethercard.\n", dev->name); + printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); ei_close(dev); return 0; } static void hydra_reset_8390(struct net_device *dev) { - printk("Hydra hw reset not there\n"); + printk(KERN_INFO "Hydra hw reset not there\n"); } static void hydra_get_8390_hdr(struct net_device *dev, diff -Nru a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c --- a/drivers/net/irda/ali-ircc.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/irda/ali-ircc.c Sun Apr 18 13:42:40 2004 @@ -44,7 +44,7 @@ #include #include -#include +#include "ali-ircc.h" #define CHIP_IO_EXTENT 8 #define BROKEN_DONGLE_ID diff -Nru a/drivers/net/irda/ali-ircc.h b/drivers/net/irda/ali-ircc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/ali-ircc.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,228 @@ +/********************************************************************* + * + * Filename: ali-ircc.h + * Version: 0.5 + * Description: Driver for the ALI M1535D and M1543C FIR Controller + * Status: Experimental. + * Author: Benjamin Kong + * Created at: 2000/10/16 03:46PM + * Modified at: 2001/1/3 02:56PM + * Modified by: Benjamin Kong + * + * Copyright (c) 2000 Benjamin Kong + * All Rights Reserved + * + * 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. + * + ********************************************************************/ + +#ifndef ALI_IRCC_H +#define ALI_IRCC_H + +#include + +#include +#include +#include + +/* SIR Register */ +/* Usr definition of linux/serial_reg.h */ + +/* FIR Register */ +#define BANK0 0x20 +#define BANK1 0x21 +#define BANK2 0x22 +#define BANK3 0x23 + +#define FIR_MCR 0x07 /* Master Control Register */ + +/* Bank 0 */ +#define FIR_DR 0x00 /* Alias 0, FIR Data Register (R/W) */ +#define FIR_IER 0x01 /* Alias 1, FIR Interrupt Enable Register (R/W) */ +#define FIR_IIR 0x02 /* Alias 2, FIR Interrupt Identification Register (Read only) */ +#define FIR_LCR_A 0x03 /* Alias 3, FIR Line Control Register A (R/W) */ +#define FIR_LCR_B 0x04 /* Alias 4, FIR Line Control Register B (R/W) */ +#define FIR_LSR 0x05 /* Alias 5, FIR Line Status Register (R/W) */ +#define FIR_BSR 0x06 /* Alias 6, FIR Bus Status Register (Read only) */ + + + /* Alias 1 */ + #define IER_FIFO 0x10 /* FIR FIFO Interrupt Enable */ + #define IER_TIMER 0x20 /* Timer Interrupt Enable */ + #define IER_EOM 0x40 /* End of Message Interrupt Enable */ + #define IER_ACT 0x80 /* Active Frame Interrupt Enable */ + + /* Alias 2 */ + #define IIR_FIFO 0x10 /* FIR FIFO Interrupt */ + #define IIR_TIMER 0x20 /* Timer Interrupt */ + #define IIR_EOM 0x40 /* End of Message Interrupt */ + #define IIR_ACT 0x80 /* Active Frame Interrupt */ + + /* Alias 3 */ + #define LCR_A_FIFO_RESET 0x80 /* FIFO Reset */ + + /* Alias 4 */ + #define LCR_B_BW 0x10 /* Brick Wall */ + #define LCR_B_SIP 0x20 /* SIP Enable */ + #define LCR_B_TX_MODE 0x40 /* Transmit Mode */ + #define LCR_B_RX_MODE 0x80 /* Receive Mode */ + + /* Alias 5 */ + #define LSR_FIR_LSA 0x00 /* FIR Line Status Address */ + #define LSR_FRAME_ABORT 0x08 /* Frame Abort */ + #define LSR_CRC_ERROR 0x10 /* CRC Error */ + #define LSR_SIZE_ERROR 0x20 /* Size Error */ + #define LSR_FRAME_ERROR 0x40 /* Frame Error */ + #define LSR_FIFO_UR 0x80 /* FIFO Underrun */ + #define LSR_FIFO_OR 0x80 /* FIFO Overrun */ + + /* Alias 6 */ + #define BSR_FIFO_NOT_EMPTY 0x80 /* FIFO Not Empty */ + +/* Bank 1 */ +#define FIR_CR 0x00 /* Alias 0, FIR Configuration Register (R/W) */ +#define FIR_FIFO_TR 0x01 /* Alias 1, FIR FIFO Threshold Register (R/W) */ +#define FIR_DMA_TR 0x02 /* Alias 2, FIR DMA Threshold Register (R/W) */ +#define FIR_TIMER_IIR 0x03 /* Alias 3, FIR Timer interrupt interval register (W/O) */ +#define FIR_FIFO_FR 0x03 /* Alias 3, FIR FIFO Flag register (R/O) */ +#define FIR_FIFO_RAR 0x04 /* Alias 4, FIR FIFO Read Address register (R/O) */ +#define FIR_FIFO_WAR 0x05 /* Alias 5, FIR FIFO Write Address register (R/O) */ +#define FIR_TR 0x06 /* Alias 6, Test REgister (W/O) */ + + /* Alias 0 */ + #define CR_DMA_EN 0x01 /* DMA Enable */ + #define CR_DMA_BURST 0x02 /* DMA Burst Mode */ + #define CR_TIMER_EN 0x08 /* Timer Enable */ + + /* Alias 3 */ + #define TIMER_IIR_500 0x00 /* 500 us */ + #define TIMER_IIR_1ms 0x01 /* 1 ms */ + #define TIMER_IIR_2ms 0x02 /* 2 ms */ + #define TIMER_IIR_4ms 0x03 /* 4 ms */ + +/* Bank 2 */ +#define FIR_IRDA_CR 0x00 /* Alias 0, IrDA Control Register (R/W) */ +#define FIR_BOF_CR 0x01 /* Alias 1, BOF Count Register (R/W) */ +#define FIR_BW_CR 0x02 /* Alias 2, Brick Wall Count Register (R/W) */ +#define FIR_TX_DSR_HI 0x03 /* Alias 3, TX Data Size Register (high) (R/W) */ +#define FIR_TX_DSR_LO 0x04 /* Alias 4, TX Data Size Register (low) (R/W) */ +#define FIR_RX_DSR_HI 0x05 /* Alias 5, RX Data Size Register (high) (R/W) */ +#define FIR_RX_DSR_LO 0x06 /* Alias 6, RX Data Size Register (low) (R/W) */ + + /* Alias 0 */ + #define IRDA_CR_HDLC1152 0x80 /* 1.152Mbps HDLC Select */ + #define IRDA_CR_CRC 0X40 /* CRC Select. */ + #define IRDA_CR_HDLC 0x20 /* HDLC select. */ + #define IRDA_CR_HP_MODE 0x10 /* HP mode (read only) */ + #define IRDA_CR_SD_ST 0x08 /* SD/MODE State. */ + #define IRDA_CR_FIR_SIN 0x04 /* FIR SIN Select. */ + #define IRDA_CR_ITTX_0 0x02 /* SOUT State. IRTX force to 0 */ + #define IRDA_CR_ITTX_1 0x03 /* SOUT State. IRTX force to 1 */ + +/* Bank 3 */ +#define FIR_ID_VR 0x00 /* Alias 0, FIR ID Version Register (R/O) */ +#define FIR_MODULE_CR 0x01 /* Alias 1, FIR Module Control Register (R/W) */ +#define FIR_IO_BASE_HI 0x02 /* Alias 2, FIR Higher I/O Base Address Register (R/O) */ +#define FIR_IO_BASE_LO 0x03 /* Alias 3, FIR Lower I/O Base Address Register (R/O) */ +#define FIR_IRQ_CR 0x04 /* Alias 4, FIR IRQ Channel Register (R/O) */ +#define FIR_DMA_CR 0x05 /* Alias 5, FIR DMA Channel Register (R/O) */ + +struct ali_chip { + char *name; + int cfg[2]; + unsigned char entr1; + unsigned char entr2; + unsigned char cid_index; + unsigned char cid_value; + int (*probe)(struct ali_chip *chip, chipio_t *info); + int (*init)(struct ali_chip *chip, chipio_t *info); +}; +typedef struct ali_chip ali_chip_t; + + +/* DMA modes needed */ +#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ +#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ + +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +#define TX_FIFO_Threshold 8 +#define RX_FIFO_Threshold 1 +#define TX_DMA_Threshold 1 +#define RX_DMA_Threshold 1 + +/* For storing entries in the status FIFO */ + +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Lenght of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + +/* Private data for each instance */ +struct ali_ircc_cb { + + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u8 ier; /* Interrupt enable register */ + + __u8 InterruptID; /* Interrupt ID */ + __u8 BusStatus; /* Bus Status */ + __u8 LineStatus; /* Line Status */ + + unsigned char rcvFramesOverflow; + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u32 new_speed; + int index; /* Instance index */ + + unsigned char fifo_opti_buf; + + struct pm_dev *dev; +}; + +static inline void switch_bank(int iobase, int bank) +{ + outb(bank, iobase+FIR_MCR); +} + +#endif /* ALI_IRCC_H */ diff -Nru a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/au1000_ircc.h Sun Apr 18 13:42:40 2004 @@ -0,0 +1,127 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Au1000 IrDA driver. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 AU1000_IRCC_H +#define AU1000_IRCC_H + +#include + +#include +#include +#include + +#define NUM_IR_IFF 1 +#define NUM_IR_DESC 64 +#define RING_SIZE_4 0x0 +#define RING_SIZE_16 0x3 +#define RING_SIZE_64 0xF +#define MAX_NUM_IR_DESC 64 +#define MAX_BUF_SIZE 2048 + +#define BPS_115200 0 +#define BPS_57600 1 +#define BPS_38400 2 +#define BPS_19200 5 +#define BPS_9600 11 +#define BPS_2400 47 + +/* Ring descriptor flags */ +#define AU_OWN (1<<7) /* tx,rx */ + +#define IR_DIS_CRC (1<<6) /* tx */ +#define IR_BAD_CRC (1<<5) /* tx */ +#define IR_NEED_PULSE (1<<4) /* tx */ +#define IR_FORCE_UNDER (1<<3) /* tx */ +#define IR_DISABLE_TX (1<<2) /* tx */ +#define IR_HW_UNDER (1<<0) /* tx */ +#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) + +#define IR_PHY_ERROR (1<<6) /* rx */ +#define IR_CRC_ERROR (1<<5) /* rx */ +#define IR_MAX_LEN (1<<4) /* rx */ +#define IR_FIFO_OVER (1<<3) /* rx */ +#define IR_SIR_ERROR (1<<2) /* rx */ +#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ + IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) + +typedef struct db_dest { + struct db_dest *pnext; + volatile u32 *vaddr; + dma_addr_t dma_addr; +} db_dest_t; + + +typedef struct ring_desc { + u8 count_0; /* 7:0 */ + u8 count_1; /* 12:8 */ + u8 reserved; + u8 flags; + u8 addr_0; /* 7:0 */ + u8 addr_1; /* 15:8 */ + u8 addr_2; /* 23:16 */ + u8 addr_3; /* 31:24 */ +} ring_dest_t; + + +/* Private data for each instance */ +struct au1k_private { + + db_dest_t *pDBfree; + db_dest_t db[2*NUM_IR_DESC]; + volatile ring_dest_t *rx_ring[NUM_IR_DESC]; + volatile ring_dest_t *tx_ring[NUM_IR_DESC]; + db_dest_t *rx_db_inuse[NUM_IR_DESC]; + db_dest_t *tx_db_inuse[NUM_IR_DESC]; + u32 rx_head; + u32 tx_head; + u32 tx_tail; + u32 tx_full; + + iobuff_t rx_buff; + + struct net_device *netdev; + struct net_device_stats stats; + + struct timeval stamp; + struct timeval now; + struct qos_info qos; + struct irlap_cb *irlap; + + u8 open; + u32 speed; + u32 newspeed; + + u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ + struct timer_list timer; + + spinlock_t lock; /* For serializing operations */ + struct pm_dev *dev; +}; +#endif /* AU1000_IRCC_H */ diff -Nru a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c --- a/drivers/net/irda/au1k_ir.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/irda/au1k_ir.c Sun Apr 18 13:42:41 2004 @@ -52,7 +52,7 @@ #include #include #include -#include "net/irda/au1000_ircc.h" +#include "au1000_ircc.h" static int au1k_irda_net_init(struct net_device *); static int au1k_irda_start(struct net_device *); diff -Nru a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c --- a/drivers/net/irda/donauboe.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/irda/donauboe.c Sun Apr 18 13:42:41 2004 @@ -55,10 +55,6 @@ /* See below for a description of the logic in this driver */ -/* Is irda_crc16_table[] exported? not yet */ -/* define this if you get errors about multiple defns of irda_crc16_table */ -#undef CRC_EXPORTED - /* User servicable parts */ /* USE_PROBE Create the code which probes the chip and does a few tests */ /* do_probe module parameter Enable this code */ @@ -209,47 +205,6 @@ /**********************************************************************/ -/* Fcs code */ - -#ifdef CRC_EXPORTED -extern __u16 const irda_crc16_table[]; -#else -static __u16 const irda_crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; -#endif - static int toshoboe_checkfcs (unsigned char *buf, int len) { @@ -1669,7 +1624,7 @@ /*We need to align the taskfile on a taskfile size boundary */ { - __u32 addr; + unsigned long addr; addr = (__u32) self->ringbuf; addr &= ~(OBOE_RING_LEN - 1); diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c --- a/drivers/net/irda/irda-usb.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/irda/irda-usb.c Sun Apr 18 13:42:41 2004 @@ -62,7 +62,7 @@ #include #include -#include +#include "irda-usb.h" /*------------------------------------------------------------------*/ diff -Nru a/drivers/net/irda/irda-usb.h b/drivers/net/irda/irda-usb.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/irda-usb.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,163 @@ +/***************************************************************************** + * + * Filename: irda-usb.h + * Version: 0.9b + * Description: IrDA-USB Driver + * Status: Experimental + * Author: Dag Brattli + * + * Copyright (C) 2001, Roman Weissgaerber + * Copyright (C) 2000, Dag Brattli + * Copyright (C) 2001, Jean Tourrilhes + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include + +#include +#include /* struct irlap_cb */ + +#define RX_COPY_THRESHOLD 200 +#define IRDA_USB_MAX_MTU 2051 +#define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ + +/* Maximum number of active URB on the Rx path + * This is the amount of buffers the we keep between the USB harware and the + * IrDA stack. + * + * Note : the network layer does also queue the packets between us and the + * IrDA stack, and is actually pretty fast and efficient in doing that. + * Therefore, we don't need to have a large number of URBs, and we can + * perfectly live happy with only one. We certainly don't need to keep the + * full IrTTP window around here... + * I repeat for those who have trouble to understand : 1 URB is plenty + * good enough to handle back-to-back (brickwalled) frames. I tried it, + * it works (it's the hardware that has trouble doing it). + * + * Having 2 URBs would allow the USB stack to process one URB while we take + * care of the other and then swap the URBs... + * On the other hand, increasing the number of URB will have penalities + * in term of latency and will interact with the link management in IrLAP... + * Jean II */ +#define IU_MAX_ACTIVE_RX_URBS 1 /* Don't touch !!! */ + +/* When a Rx URB is passed back to us, we can't reuse it immediately, + * because it may still be referenced by the USB layer. Therefore we + * need to keep one extra URB in the Rx path. + * Jean II */ +#define IU_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + 1) + +/* Various ugly stuff to try to workaround generic problems */ +/* Send speed command in case of timeout, just for trying to get things sane */ +#define IU_BUG_KICK_TIMEOUT +/* Show the USB class descriptor */ +#undef IU_DUMP_CLASS_DESC +/* Assume a minimum round trip latency for USB transfer (in us)... + * USB transfer are done in the next USB slot if there is no traffic + * (1/19 msec) and is done at 12 Mb/s : + * Waiting for slot + tx = (53us + 16us) * 2 = 137us minimum. + * Rx notification will only be done at the end of the USB frame period : + * OHCI : frame period = 1ms + * UHCI : frame period = 1ms, but notification can take 2 or 3 ms :-( + * EHCI : frame period = 125us */ +#define IU_USB_MIN_RTT 500 /* This should be safe in most cases */ + +/* Inbound header */ +#define MEDIA_BUSY 0x80 + +#define SPEED_2400 0x01 +#define SPEED_9600 0x02 +#define SPEED_19200 0x03 +#define SPEED_38400 0x04 +#define SPEED_57600 0x05 +#define SPEED_115200 0x06 +#define SPEED_576000 0x07 +#define SPEED_1152000 0x08 +#define SPEED_4000000 0x09 + +/* Basic capabilities */ +#define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ +/* Main bugs */ +#define IUC_SPEED_BUG 0x01 /* Device doesn't set speed after the frame */ +#define IUC_NO_WINDOW 0x02 /* Device doesn't behave with big Rx window */ +#define IUC_NO_TURN 0x04 /* Device doesn't do turnaround by itself */ +/* Not currently used */ +#define IUC_SIR_ONLY 0x08 /* Device doesn't behave at FIR speeds */ +#define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ +#define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ +#define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ + +/* USB class definitions */ +#define USB_IRDA_HEADER 0x01 +#define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ +#define USB_DT_IRDA 0x21 + +struct irda_class_desc { + __u8 bLength; + __u8 bDescriptorType; + __u16 bcdSpecRevision; + __u8 bmDataSize; + __u8 bmWindowSize; + __u8 bmMinTurnaroundTime; + __u16 wBaudRate; + __u8 bmAdditionalBOFs; + __u8 bIrdaRateSniff; + __u8 bMaxUnicastList; +} __attribute__ ((packed)); + +/* class specific interface request to get the IrDA-USB class descriptor + * (6.2.5, USB-IrDA class spec 1.0) */ + +#define IU_REQ_GET_CLASS_DESC 0x06 + +struct irda_usb_cb { + struct irda_class_desc *irda_desc; + struct usb_device *usbdev; /* init: probe_irda */ + struct usb_interface *usbintf; /* init: probe_irda */ + int netopen; /* Device is active for network */ + int present; /* Device is present on the bus */ + __u32 capability; /* Capability of the hardware */ + __u8 bulk_in_ep; /* Rx Endpoint assignments */ + __u8 bulk_out_ep; /* Tx Endpoint assignments */ + __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ + __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ + + wait_queue_head_t wait_q; /* for timeouts */ + + struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ + struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ + struct urb *tx_urb; /* URB used to send data frames */ + struct urb *speed_urb; /* URB used to send speed commands */ + + struct net_device *netdev; /* Yes! we are some kind of netdev. */ + struct net_device_stats stats; + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; + hashbin_t *tx_list; /* Queued transmit skb's */ + char *speed_buff; /* Buffer for speed changes */ + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u16 xbofs; /* Current xbofs setting */ + __s16 new_xbofs; /* xbofs we need to set */ + __u32 speed; /* Current speed */ + __s32 new_speed; /* speed we need to set */ +}; + diff -Nru a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c --- a/drivers/net/irda/irport.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/irda/irport.c Sun Apr 18 13:42:41 2004 @@ -58,7 +58,7 @@ #include #include -#include +#include "irport.h" #define IO_EXTENT 8 diff -Nru a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/irport.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,90 @@ +/********************************************************************* + * + * Filename: irport.h + * Version: 0.1 + * Description: Serial driver for IrDA + * Status: Experimental. + * Author: Dag Brattli + * Created at: Sun Aug 3 13:49:59 1997 + * Modified at: Fri Jan 14 10:21:10 2000 + * Modified by: Dag Brattli + * + * Copyright (c) 1997, 1998-2000 Dag Brattli + * All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef IRPORT_H +#define IRPORT_H + +#include +#include +#include +#include + +#include + +#define SPEED_DEFAULT 9600 +#define SPEED_MAX 115200 + +/* + * These are the supported serial types. + */ +#define PORT_UNKNOWN 0 +#define PORT_8250 1 +#define PORT_16450 2 +#define PORT_16550 3 +#define PORT_16550A 4 +#define PORT_CIRRUS 5 +#define PORT_16650 6 +#define PORT_MAX 6 + +#define FRAME_MAX_SIZE 2048 + +struct irport_cb { + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are attached to */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + struct qos_info qos; /* QoS capabilities for this device */ + dongle_t *dongle; /* Dongle driver */ + + __u32 flags; /* Interface flags */ + __u32 new_speed; + int mode; + int index; /* Instance index */ + int transmitting; /* Are we transmitting ? */ + + spinlock_t lock; /* For serializing operations */ + + /* For piggyback drivers */ + void *priv; + void (*change_speed)(void *priv, __u32 speed); + int (*interrupt)(int irq, void *dev_id, struct pt_regs *regs); +}; + +struct irport_cb *irport_open(int i, unsigned int iobase, unsigned int irq); +int irport_close(struct irport_cb *self); +void irport_start(struct irport_cb *self); +void irport_stop(struct irport_cb *self); +void irport_change_speed(void *priv, __u32 speed); +irqreturn_t irport_interrupt(int irq, void *dev_id, struct pt_regs *regs); +int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); +int irport_net_open(struct net_device *dev); +int irport_net_close(struct net_device *dev); + +#endif /* IRPORT_H */ diff -Nru a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c --- a/drivers/net/irda/nsc-ircc.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/irda/nsc-ircc.c Sun Apr 18 13:42:40 2004 @@ -63,7 +63,7 @@ #include #include -#include +#include "nsc-ircc.h" #define CHIP_IO_EXTENT 8 #define BROKEN_DONGLE_ID diff -Nru a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/nsc-ircc.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,277 @@ +/********************************************************************* + * + * Filename: nsc-ircc.h + * Version: + * Description: + * Status: Experimental. + * Author: Dag Brattli + * Created at: Fri Nov 13 14:37:40 1998 + * Modified at: Sun Jan 23 17:47:00 2000 + * Modified by: Dag Brattli + * + * Copyright (c) 1998-2000 Dag Brattli + * Copyright (c) 1998 Lichen Wang, + * Copyright (c) 1998 Actisys Corp., www.actisys.com + * All Rights Reserved + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef NSC_IRCC_H +#define NSC_IRCC_H + +#include + +#include +#include +#include + +/* DMA modes needed */ +#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ +#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ + +/* Config registers for the '108 */ +#define CFG_108_BAIC 0x00 +#define CFG_108_CSRT 0x01 +#define CFG_108_MCTL 0x02 + +/* Config registers for the '338 */ +#define CFG_338_FER 0x00 +#define CFG_338_FAR 0x01 +#define CFG_338_PTR 0x02 +#define CFG_338_PNP0 0x1b +#define CFG_338_PNP1 0x1c +#define CFG_338_PNP3 0x4f + +/* Config registers for the '39x (in the logical device bank) */ +#define CFG_39X_LDN 0x07 /* Logical device number (Super I/O bank) */ +#define CFG_39X_SIOCF1 0x21 /* SuperI/O Config */ +#define CFG_39X_ACT 0x30 /* Device activation */ +#define CFG_39X_BASEH 0x60 /* Device base address (high bits) */ +#define CFG_39X_BASEL 0x61 /* Device base address (low bits) */ +#define CFG_39X_IRQNUM 0x70 /* Interrupt number & wake up enable */ +#define CFG_39X_IRQSEL 0x71 /* Interrupt select (edge/level + polarity) */ +#define CFG_39X_DMA0 0x74 /* DMA 0 configuration */ +#define CFG_39X_DMA1 0x75 /* DMA 1 configuration */ +#define CFG_39X_SPC 0xF0 /* Serial port configuration register */ + +/* Flags for configuration register CRF0 */ +#define APEDCRC 0x02 +#define ENBNKSEL 0x01 + +/* Set 0 */ +#define TXD 0x00 /* Transmit data port */ +#define RXD 0x00 /* Receive data port */ + +/* Register 1 */ +#define IER 0x01 /* Interrupt Enable Register*/ +#define IER_RXHDL_IE 0x01 /* Receiver high data level interrupt */ +#define IER_TXLDL_IE 0x02 /* Transeiver low data level interrupt */ +#define IER_LS_IE 0x04//* Link Status Interrupt */ +#define IER_ETXURI 0x04 /* Tx underrun */ +#define IER_DMA_IE 0x10 /* DMA finished interrupt */ +#define IER_TXEMP_IE 0x20 +#define IER_SFIF_IE 0x40 /* Frame status FIFO intr */ +#define IER_TMR_IE 0x80 /* Timer event */ + +#define FCR 0x02 /* (write only) */ +#define FCR_FIFO_EN 0x01 /* Enable FIFO's */ +#define FCR_RXSR 0x02 /* Rx FIFO soft reset */ +#define FCR_TXSR 0x04 /* Tx FIFO soft reset */ +#define FCR_RXTH 0x40 /* Rx FIFO threshold (set to 16) */ +#define FCR_TXTH 0x20 /* Tx FIFO threshold (set to 17) */ + +#define EIR 0x02 /* (read only) */ +#define EIR_RXHDL_EV 0x01 +#define EIR_TXLDL_EV 0x02 +#define EIR_LS_EV 0x04 +#define EIR_DMA_EV 0x10 +#define EIR_TXEMP_EV 0x20 +#define EIR_SFIF_EV 0x40 +#define EIR_TMR_EV 0x80 + +#define LCR 0x03 /* Link control register */ +#define LCR_WLS_8 0x03 /* 8 bits */ + +#define BSR 0x03 /* Bank select register */ +#define BSR_BKSE 0x80 +#define BANK0 LCR_WLS_8 /* Must make sure that we set 8N1 */ +#define BANK1 0x80 +#define BANK2 0xe0 +#define BANK3 0xe4 +#define BANK4 0xe8 +#define BANK5 0xec +#define BANK6 0xf0 +#define BANK7 0xf4 + +#define MCR 0x04 /* Mode Control Register */ +#define MCR_MODE_MASK ~(0xd0) +#define MCR_UART 0x00 +#define MCR_RESERVED 0x20 +#define MCR_SHARP_IR 0x40 +#define MCR_SIR 0x60 +#define MCR_MIR 0x80 +#define MCR_FIR 0xa0 +#define MCR_CEIR 0xb0 +#define MCR_IR_PLS 0x10 +#define MCR_DMA_EN 0x04 +#define MCR_EN_IRQ 0x08 +#define MCR_TX_DFR 0x08 + +#define LSR 0x05 /* Link status register */ +#define LSR_RXDA 0x01 /* Receiver data available */ +#define LSR_TXRDY 0x20 /* Transmitter ready */ +#define LSR_TXEMP 0x40 /* Transmitter empty */ + +#define ASCR 0x07 /* Auxillary Status and Control Register */ +#define ASCR_RXF_TOUT 0x01 /* Rx FIFO timeout */ +#define ASCR_FEND_INF 0x02 /* Frame end bytes in rx FIFO */ +#define ASCR_S_EOT 0x04 /* Set end of transmission */ +#define ASCT_RXBSY 0x20 /* Rx busy */ +#define ASCR_TXUR 0x40 /* Transeiver underrun */ +#define ASCR_CTE 0x80 /* Clear timer event */ + +/* Bank 2 */ +#define BGDL 0x00 /* Baud Generator Divisor Port (Low Byte) */ +#define BGDH 0x01 /* Baud Generator Divisor Port (High Byte) */ + +#define ECR1 0x02 /* Extended Control Register 1 */ +#define ECR1_EXT_SL 0x01 /* Extended Mode Select */ +#define ECR1_DMANF 0x02 /* DMA Fairness */ +#define ECR1_DMATH 0x04 /* DMA Threshold */ +#define ECR1_DMASWP 0x08 /* DMA Swap */ + +#define EXCR2 0x04 +#define EXCR2_TFSIZ 0x01 /* Rx FIFO size = 32 */ +#define EXCR2_RFSIZ 0x04 /* Tx FIFO size = 32 */ + +#define TXFLV 0x06 /* Tx FIFO level */ +#define RXFLV 0x07 /* Rx FIFO level */ + +/* Bank 3 */ +#define MID 0x00 + +/* Bank 4 */ +#define TMRL 0x00 /* Timer low byte */ +#define TMRH 0x01 /* Timer high byte */ +#define IRCR1 0x02 /* Infrared control register 1 */ +#define IRCR1_TMR_EN 0x01 /* Timer enable */ + +#define TFRLL 0x04 +#define TFRLH 0x05 +#define RFRLL 0x06 +#define RFRLH 0x07 + +/* Bank 5 */ +#define IRCR2 0x04 /* Infrared control register 2 */ +#define IRCR2_MDRS 0x04 /* MIR data rate select */ +#define IRCR2_FEND_MD 0x20 /* */ + +#define FRM_ST 0x05 /* Frame status FIFO */ +#define FRM_ST_VLD 0x80 /* Frame status FIFO data valid */ +#define FRM_ST_ERR_MSK 0x5f +#define FRM_ST_LOST_FR 0x40 /* Frame lost */ +#define FRM_ST_MAX_LEN 0x10 /* Max frame len exceeded */ +#define FRM_ST_PHY_ERR 0x08 /* Physical layer error */ +#define FRM_ST_BAD_CRC 0x04 +#define FRM_ST_OVR1 0x02 /* Rx FIFO overrun */ +#define FRM_ST_OVR2 0x01 /* Frame status FIFO overrun */ + +#define RFLFL 0x06 +#define RFLFH 0x07 + +/* Bank 6 */ +#define IR_CFG2 0x00 +#define IR_CFG2_DIS_CRC 0x02 + +/* Bank 7 */ +#define IRM_CR 0x07 /* Infrared module control register */ +#define IRM_CR_IRX_MSL 0x40 +#define IRM_CR_AF_MNT 0x80 /* Automatic format */ + +/* NSC chip information */ +struct nsc_chip { + char *name; /* Name of chipset */ + int cfg[3]; /* Config registers */ + u_int8_t cid_index; /* Chip identification index reg */ + u_int8_t cid_value; /* Chip identification expected value */ + u_int8_t cid_mask; /* Chip identification revision mask */ + + /* Functions for probing and initializing the specific chip */ + int (*probe)(struct nsc_chip *chip, chipio_t *info); + int (*init)(struct nsc_chip *chip, chipio_t *info); +}; +typedef struct nsc_chip nsc_chip_t; + +/* For storing entries in the status FIFO */ +struct st_fifo_entry { + int status; + int len; +}; + +#define MAX_TX_WINDOW 7 +#define MAX_RX_WINDOW 7 + +struct st_fifo { + struct st_fifo_entry entries[MAX_RX_WINDOW]; + int pending_bytes; + int head; + int tail; + int len; +}; + +struct frame_cb { + void *start; /* Start of frame in DMA mem */ + int len; /* Lenght of frame in DMA mem */ +}; + +struct tx_fifo { + struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ + int ptr; /* Currently being sent */ + int len; /* Lenght of queue */ + int free; /* Next free slot */ + void *tail; /* Next free start in DMA mem */ +}; + +/* Private data for each instance */ +struct nsc_ircc_cb { + struct st_fifo st_fifo; /* Info about received frames */ + struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + __u8 ier; /* Interrupt enable register */ + + struct timeval stamp; + struct timeval now; + + spinlock_t lock; /* For serializing operations */ + + __u32 new_speed; + int index; /* Instance index */ + + struct pm_dev *dev; +}; + +static inline void switch_bank(int iobase, int bank) +{ + outb(bank, iobase+BSR); +} + +#endif /* NSC_IRCC_H */ diff -Nru a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c --- a/drivers/net/irda/sir_dev.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/irda/sir_dev.c Sun Apr 18 13:42:41 2004 @@ -240,7 +240,8 @@ } if (!dev->irlap) { - WARNING("%s - too early: %p / %d!\n", __FUNCTION__, cp, count); + WARNING("%s - too early: %p / %zd!\n", + __FUNCTION__, cp, count); return -1; } @@ -250,7 +251,7 @@ */ irda_device_set_media_busy(dev->netdev, TRUE); dev->stats.rx_dropped++; - IRDA_DEBUG(0, "%s; rx-drop: %d\n", __FUNCTION__, count); + IRDA_DEBUG(0, "%s; rx-drop: %zd\n", __FUNCTION__, count); return 0; } diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c --- a/drivers/net/irda/vlsi_ir.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/irda/vlsi_ir.c Sun Apr 18 13:42:40 2004 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,7 @@ #include #include -#include +#include "vlsi_ir.h" /********************************************************/ @@ -160,72 +161,64 @@ #ifdef CONFIG_PROC_FS -static int vlsi_proc_pdev(struct pci_dev *pdev, char *buf, int len) +static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) { unsigned iobase = pci_resource_start(pdev, 0); unsigned i; - char *out = buf; - if (len < 500) - return 0; - - out += sprintf(out, "\n%s (vid/did: %04x/%04x)\n", - PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); - out += sprintf(out, "pci-power-state: %u\n", (unsigned) pdev->current_state); - out += sprintf(out, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", - pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); - out += sprintf(out, "hw registers: "); + seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n", + PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device); + seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state); + seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", + pdev->irq, (unsigned)pci_resource_start(pdev, 0), (unsigned long long)pdev->dma_mask); + seq_printf(seq, "hw registers: "); for (i = 0; i < 0x20; i++) - out += sprintf(out, "%02x", (unsigned)inb((iobase+i))); - out += sprintf(out, "\n"); - return out - buf; + seq_printf(seq, "%02x", (unsigned)inb((iobase+i))); + seq_printf(seq, "\n"); } -static int vlsi_proc_ndev(struct net_device *ndev, char *buf, int len) +static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev) { vlsi_irda_dev_t *idev = ndev->priv; - char *out = buf; u8 byte; u16 word; unsigned delta1, delta2; struct timeval now; unsigned iobase = ndev->base_addr; - if (len < 1000) - return 0; - - out += sprintf(out, "\n%s link state: %s / %s / %s / %s\n", ndev->name, + seq_printf(seq, "\n%s link state: %s / %s / %s / %s\n", ndev->name, netif_device_present(ndev) ? "attached" : "detached", netif_running(ndev) ? "running" : "not running", netif_carrier_ok(ndev) ? "carrier ok" : "no carrier", netif_queue_stopped(ndev) ? "queue stopped" : "queue running"); + if (!netif_running(ndev)) - return out - buf; + return; - out += sprintf(out, "\nhw-state:\n"); + seq_printf(seq, "\nhw-state:\n"); pci_read_config_byte(idev->pdev, VLSI_PCI_IRMISC, &byte); - out += sprintf(out, "IRMISC:%s%s%s uart%s", + seq_printf(seq, "IRMISC:%s%s%s uart%s", (byte&IRMISC_IRRAIL) ? " irrail" : "", (byte&IRMISC_IRPD) ? " irpd" : "", (byte&IRMISC_UARTTST) ? " uarttest" : "", (byte&IRMISC_UARTEN) ? "@" : " disabled\n"); if (byte&IRMISC_UARTEN) { - out += sprintf(out, "0x%s\n", + seq_printf(seq, "0x%s\n", (byte&2) ? ((byte&1) ? "3e8" : "2e8") : ((byte&1) ? "3f8" : "2f8")); } pci_read_config_byte(idev->pdev, VLSI_PCI_CLKCTL, &byte); - out += sprintf(out, "CLKCTL: PLL %s%s%s / clock %s / wakeup %s\n", + seq_printf(seq, "CLKCTL: PLL %s%s%s / clock %s / wakeup %s\n", (byte&CLKCTL_PD_INV) ? "powered" : "down", (byte&CLKCTL_LOCK) ? " locked" : "", (byte&CLKCTL_EXTCLK) ? ((byte&CLKCTL_XCKSEL)?" / 40 MHz XCLK":" / 48 MHz XCLK") : "", (byte&CLKCTL_CLKSTP) ? "stopped" : "running", (byte&CLKCTL_WAKE) ? "enabled" : "disabled"); pci_read_config_byte(idev->pdev, VLSI_PCI_MSTRPAGE, &byte); - out += sprintf(out, "MSTRPAGE: 0x%02x\n", (unsigned)byte); + seq_printf(seq, "MSTRPAGE: 0x%02x\n", (unsigned)byte); byte = inb(iobase+VLSI_PIO_IRINTR); - out += sprintf(out, "IRINTR:%s%s%s%s%s%s%s%s\n", + seq_printf(seq, "IRINTR:%s%s%s%s%s%s%s%s\n", (byte&IRINTR_ACTEN) ? " ACTEN" : "", (byte&IRINTR_RPKTEN) ? " RPKTEN" : "", (byte&IRINTR_TPKTEN) ? " TPKTEN" : "", @@ -235,16 +228,16 @@ (byte&IRINTR_TPKTINT) ? " TPKTINT" : "", (byte&IRINTR_OE_INT) ? " OE_INT" : ""); word = inw(iobase+VLSI_PIO_RINGPTR); - out += sprintf(out, "RINGPTR: rx=%u / tx=%u\n", RINGPTR_GET_RX(word), RINGPTR_GET_TX(word)); + seq_printf(seq, "RINGPTR: rx=%u / tx=%u\n", RINGPTR_GET_RX(word), RINGPTR_GET_TX(word)); word = inw(iobase+VLSI_PIO_RINGBASE); - out += sprintf(out, "RINGBASE: busmap=0x%08x\n", + seq_printf(seq, "RINGBASE: busmap=0x%08x\n", ((unsigned)word << 10)|(MSTRPAGE_VALUE<<24)); word = inw(iobase+VLSI_PIO_RINGSIZE); - out += sprintf(out, "RINGSIZE: rx=%u / tx=%u\n", RINGSIZE_TO_RXSIZE(word), + seq_printf(seq, "RINGSIZE: rx=%u / tx=%u\n", RINGSIZE_TO_RXSIZE(word), RINGSIZE_TO_TXSIZE(word)); word = inw(iobase+VLSI_PIO_IRCFG); - out += sprintf(out, "IRCFG:%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + seq_printf(seq, "IRCFG:%s%s%s%s%s%s%s%s%s%s%s%s%s\n", (word&IRCFG_LOOP) ? " LOOP" : "", (word&IRCFG_ENTX) ? " ENTX" : "", (word&IRCFG_ENRX) ? " ENRX" : "", @@ -259,7 +252,7 @@ (word&IRCFG_TXPOL) ? " TXPOL" : "", (word&IRCFG_RXPOL) ? " RXPOL" : ""); word = inw(iobase+VLSI_PIO_IRENABLE); - out += sprintf(out, "IRENABLE:%s%s%s%s%s%s%s%s\n", + seq_printf(seq, "IRENABLE:%s%s%s%s%s%s%s%s\n", (word&IRENABLE_PHYANDCLOCK) ? " PHYANDCLOCK" : "", (word&IRENABLE_CFGER) ? " CFGERR" : "", (word&IRENABLE_FIR_ON) ? " FIR_ON" : "", @@ -269,22 +262,22 @@ (word&IRENABLE_ENRXST) ? " ENRXST" : "", (word&IRENABLE_CRC16_ON) ? " CRC16_ON" : ""); word = inw(iobase+VLSI_PIO_PHYCTL); - out += sprintf(out, "PHYCTL: baud-divisor=%u / pulsewidth=%u / preamble=%u\n", + seq_printf(seq, "PHYCTL: baud-divisor=%u / pulsewidth=%u / preamble=%u\n", (unsigned)PHYCTL_TO_BAUD(word), (unsigned)PHYCTL_TO_PLSWID(word), (unsigned)PHYCTL_TO_PREAMB(word)); word = inw(iobase+VLSI_PIO_NPHYCTL); - out += sprintf(out, "NPHYCTL: baud-divisor=%u / pulsewidth=%u / preamble=%u\n", + seq_printf(seq, "NPHYCTL: baud-divisor=%u / pulsewidth=%u / preamble=%u\n", (unsigned)PHYCTL_TO_BAUD(word), (unsigned)PHYCTL_TO_PLSWID(word), (unsigned)PHYCTL_TO_PREAMB(word)); word = inw(iobase+VLSI_PIO_MAXPKT); - out += sprintf(out, "MAXPKT: max. rx packet size = %u\n", word); + seq_printf(seq, "MAXPKT: max. rx packet size = %u\n", word); word = inw(iobase+VLSI_PIO_RCVBCNT) & RCVBCNT_MASK; - out += sprintf(out, "RCVBCNT: rx-fifo filling level = %u\n", word); + seq_printf(seq, "RCVBCNT: rx-fifo filling level = %u\n", word); - out += sprintf(out, "\nsw-state:\n"); - out += sprintf(out, "IrPHY setup: %d baud - %s encoding\n", idev->baud, + seq_printf(seq, "\nsw-state:\n"); + seq_printf(seq, "IrPHY setup: %d baud - %s encoding\n", idev->baud, (idev->mode==IFF_SIR)?"SIR":((idev->mode==IFF_MIR)?"MIR":"FIR")); do_gettimeofday(&now); if (now.tv_usec >= idev->last_rx.tv_usec) { @@ -295,216 +288,110 @@ delta2 = 1000000 + now.tv_usec - idev->last_rx.tv_usec; delta1 = 1; } - out += sprintf(out, "last rx: %lu.%06u sec\n", + seq_printf(seq, "last rx: %lu.%06u sec\n", now.tv_sec - idev->last_rx.tv_sec - delta1, delta2); - out += sprintf(out, "RX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu", + seq_printf(seq, "RX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu", idev->stats.rx_packets, idev->stats.rx_bytes, idev->stats.rx_errors, idev->stats.rx_dropped); - out += sprintf(out, " / overrun=%lu / length=%lu / frame=%lu / crc=%lu\n", + seq_printf(seq, " / overrun=%lu / length=%lu / frame=%lu / crc=%lu\n", idev->stats.rx_over_errors, idev->stats.rx_length_errors, idev->stats.rx_frame_errors, idev->stats.rx_crc_errors); - out += sprintf(out, "TX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu / fifo=%lu\n", + seq_printf(seq, "TX: packets=%lu / bytes=%lu / errors=%lu / dropped=%lu / fifo=%lu\n", idev->stats.tx_packets, idev->stats.tx_bytes, idev->stats.tx_errors, idev->stats.tx_dropped, idev->stats.tx_fifo_errors); - return out - buf; } -static int vlsi_proc_ring(struct vlsi_ring *r, char *buf, int len) +static void vlsi_proc_ring(struct seq_file *seq, struct vlsi_ring *r) { struct ring_descr *rd; unsigned i, j; int h, t; - char *out = buf; - - if (len < 3000) - return 0; - out += sprintf(out, "size %u / mask 0x%04x / len %u / dir %d / hw %p\n", + seq_printf(seq, "size %u / mask 0x%04x / len %u / dir %d / hw %p\n", r->size, r->mask, r->len, r->dir, r->rd[0].hw); h = atomic_read(&r->head) & r->mask; t = atomic_read(&r->tail) & r->mask; - out += sprintf(out, "head = %d / tail = %d ", h, t); + seq_printf(seq, "head = %d / tail = %d ", h, t); if (h == t) - out += sprintf(out, "(empty)\n"); + seq_printf(seq, "(empty)\n"); else { if (((t+1)&r->mask) == h) - out += sprintf(out, "(full)\n"); + seq_printf(seq, "(full)\n"); else - out += sprintf(out, "(level = %d)\n", ((unsigned)(t-h) & r->mask)); + seq_printf(seq, "(level = %d)\n", ((unsigned)(t-h) & r->mask)); rd = &r->rd[h]; j = (unsigned) rd_get_count(rd); - out += sprintf(out, "current: rd = %d / status = %02x / len = %u\n", + seq_printf(seq, "current: rd = %d / status = %02x / len = %u\n", h, (unsigned)rd_get_status(rd), j); if (j > 0) { - out += sprintf(out, " data:"); + seq_printf(seq, " data:"); if (j > 20) j = 20; for (i = 0; i < j; i++) - out += sprintf(out, " %02x", (unsigned)((unsigned char *)rd->buf)[i]); - out += sprintf(out, "\n"); + seq_printf(seq, " %02x", (unsigned)((unsigned char *)rd->buf)[i]); + seq_printf(seq, "\n"); } } for (i = 0; i < r->size; i++) { rd = &r->rd[i]; - out += sprintf(out, "> ring descr %u: ", i); - out += sprintf(out, "skb=%p data=%p hw=%p\n", rd->skb, rd->buf, rd->hw); - out += sprintf(out, " hw: status=%02x count=%u busaddr=0x%08x\n", + seq_printf(seq, "> ring descr %u: ", i); + seq_printf(seq, "skb=%p data=%p hw=%p\n", rd->skb, rd->buf, rd->hw); + seq_printf(seq, " hw: status=%02x count=%u busaddr=0x%08x\n", (unsigned) rd_get_status(rd), (unsigned) rd_get_count(rd), (unsigned) rd_get_addr(rd)); } - return out - buf; } -static int vlsi_proc_print(struct net_device *ndev, char *buf, int len) +static int vlsi_seq_show(struct seq_file *seq, void *v) { - vlsi_irda_dev_t *idev; + struct net_device *ndev = seq->private; + vlsi_irda_dev_t *idev = ndev->priv; unsigned long flags; - char *out = buf; - - if (!ndev || !ndev->priv) { - ERROR("%s: invalid ptr!\n", __FUNCTION__); - return 0; - } - - idev = ndev->priv; - if (len < 8000) - return 0; - - out += sprintf(out, "\n%s %s\n\n", DRIVER_NAME, DRIVER_VERSION); - out += sprintf(out, "clksrc: %s\n", + seq_printf(seq, "\n%s %s\n\n", DRIVER_NAME, DRIVER_VERSION); + seq_printf(seq, "clksrc: %s\n", (clksrc>=2) ? ((clksrc==3)?"40MHz XCLK":"48MHz XCLK") : ((clksrc==1)?"48MHz PLL":"autodetect")); - out += sprintf(out, "ringsize: tx=%d / rx=%d\n", + seq_printf(seq, "ringsize: tx=%d / rx=%d\n", ringsize[0], ringsize[1]); - out += sprintf(out, "sirpulse: %s\n", (sirpulse)?"3/16 bittime":"short"); - out += sprintf(out, "qos_mtt_bits: 0x%02x\n", (unsigned)qos_mtt_bits); + seq_printf(seq, "sirpulse: %s\n", (sirpulse)?"3/16 bittime":"short"); + seq_printf(seq, "qos_mtt_bits: 0x%02x\n", (unsigned)qos_mtt_bits); spin_lock_irqsave(&idev->lock, flags); if (idev->pdev != NULL) { - out += vlsi_proc_pdev(idev->pdev, out, len - (out-buf)); + vlsi_proc_pdev(seq, idev->pdev); + if (idev->pdev->current_state == 0) - out += vlsi_proc_ndev(ndev, out, len - (out-buf)); + vlsi_proc_ndev(seq, ndev); else - out += sprintf(out, "\nPCI controller down - resume_ok = %d\n", + seq_printf(seq, "\nPCI controller down - resume_ok = %d\n", idev->resume_ok); if (netif_running(ndev) && idev->rx_ring && idev->tx_ring) { - out += sprintf(out, "\n--------- RX ring -----------\n\n"); - out += vlsi_proc_ring(idev->rx_ring, out, len - (out-buf)); - out += sprintf(out, "\n--------- TX ring -----------\n\n"); - out += vlsi_proc_ring(idev->tx_ring, out, len - (out-buf)); + seq_printf(seq, "\n--------- RX ring -----------\n\n"); + vlsi_proc_ring(seq, idev->rx_ring); + seq_printf(seq, "\n--------- TX ring -----------\n\n"); + vlsi_proc_ring(seq, idev->tx_ring); } } - out += sprintf(out, "\n"); + seq_printf(seq, "\n"); spin_unlock_irqrestore(&idev->lock, flags); - return out - buf; -} - -struct vlsi_proc_data { - int size; - char *data; -}; - -/* most of the proc-fops code borrowed from usb/uhci */ - -static int vlsi_proc_open(struct inode *inode, struct file *file) -{ - const struct proc_dir_entry *pde = PDE(inode); - struct net_device *ndev = pde->data; - vlsi_irda_dev_t *idev = ndev->priv; - struct vlsi_proc_data *procdata; - const int maxdata = 8000; - - lock_kernel(); - procdata = kmalloc(sizeof(*procdata), GFP_KERNEL); - if (!procdata) { - unlock_kernel(); - return -ENOMEM; - } - procdata->data = kmalloc(maxdata, GFP_KERNEL); - if (!procdata->data) { - kfree(procdata); - unlock_kernel(); - return -ENOMEM; - } - - down(&idev->sem); - procdata->size = vlsi_proc_print(ndev, procdata->data, maxdata); - up(&idev->sem); - - file->private_data = procdata; - return 0; } -static loff_t vlsi_proc_lseek(struct file *file, loff_t off, int whence) -{ - struct vlsi_proc_data *procdata; - loff_t new = -1; - - lock_kernel(); - procdata = file->private_data; - - switch (whence) { - case 0: - new = off; - break; - case 1: - new = file->f_pos + off; - break; - } - if (new < 0 || new > procdata->size) { - unlock_kernel(); - return -EINVAL; - } - unlock_kernel(); - return (file->f_pos = new); -} - -static ssize_t vlsi_proc_read(struct file *file, char *buf, size_t nbytes, - loff_t *ppos) -{ - struct vlsi_proc_data *procdata = file->private_data; - unsigned int pos; - unsigned int size; - - pos = *ppos; - size = procdata->size; - if (pos >= size) - return 0; - if (nbytes >= size) - nbytes = size; - if (pos + nbytes > size) - nbytes = size - pos; - - if (copy_to_user(buf, procdata->data + pos, nbytes)) - return -EFAULT; - - *ppos += nbytes; - - return nbytes; -} - -static int vlsi_proc_release(struct inode *inode, struct file *file) +static int vlsi_seq_open(struct inode *inode, struct file *file) { - struct vlsi_proc_data *procdata = file->private_data; - - kfree(procdata->data); - kfree(procdata); - - return 0; + return single_open(file, vlsi_seq_show, PDE(inode)->data); } static struct file_operations vlsi_proc_fops = { - /* protect individual procdir file entry against rmmod */ - .owner = THIS_MODULE, - .open = vlsi_proc_open, - .llseek = vlsi_proc_lseek, - .read = vlsi_proc_read, - .release = vlsi_proc_release, + .owner = THIS_MODULE, + .open = vlsi_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, }; #define VLSI_PROC_FOPS (&vlsi_proc_fops) @@ -1787,13 +1674,12 @@ ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root); if (!ent) { WARNING("%s: failed to create proc entry\n", __FUNCTION__); - } - else { + } else { ent->data = ndev; ent->proc_fops = VLSI_PROC_FOPS; ent->size = 0; - idev->proc_entry = ent; } + idev->proc_entry = ent; } MESSAGE("%s: registered device %s\n", drivername, ndev->name); diff -Nru a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/vlsi_ir.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,799 @@ + +/********************************************************************* + * + * vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux + * + * Version: 0.5 + * + * Copyright (c) 2001-2003 Martin Diehl + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ********************************************************************/ + +#ifndef IRDA_VLSI_FIR_H +#define IRDA_VLSI_FIR_H + +/* ================================================================ + * compatibility stuff + */ + +/* definitions not present in pci_ids.h */ + +#ifndef PCI_CLASS_WIRELESS_IRDA +#define PCI_CLASS_WIRELESS_IRDA 0x0d00 +#endif + +#ifndef PCI_CLASS_SUBCLASS_MASK +#define PCI_CLASS_SUBCLASS_MASK 0xffff +#endif + +/* in recent 2.5 interrupt handlers have non-void return value */ +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +/* some stuff need to check kernelversion. Not all 2.5 stuff was present + * in early 2.5.x - the test is merely to separate 2.4 from 2.5 + */ +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +/* PDE() introduced in 2.5.4 */ +#ifdef CONFIG_PROC_FS +#define PDE(inode) ((inode)->u.generic_ip) +#endif + +/* irda crc16 calculation exported in 2.5.42 */ +#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) + +/* we use this for unified pci device name access */ +#define PCIDEV_NAME(pdev) ((pdev)->name) + +#else /* 2.5 or later */ + +/* recent 2.5/2.6 stores pci device names at varying places ;-) */ +#ifdef CONFIG_PCI_NAMES +/* human readable name */ +#define PCIDEV_NAME(pdev) ((pdev)->pretty_name) +#else +/* whatever we get from the associated struct device - bus:slot:dev.fn id */ +#define PCIDEV_NAME(pdev) (pci_name(pdev)) +#endif + +#endif + +/* ================================================================ */ + +/* non-standard PCI registers */ + +enum vlsi_pci_regs { + VLSI_PCI_CLKCTL = 0x40, /* chip clock input control */ + VLSI_PCI_MSTRPAGE = 0x41, /* addr [31:24] for all busmaster cycles */ + VLSI_PCI_IRMISC = 0x42 /* mainly legacy UART related */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PCI_CLKCTL: Clock Control Register (u8, rw) */ + +/* Three possible clock sources: either on-chip 48MHz PLL or + * external clock applied to EXTCLK pin. External clock may + * be either 48MHz or 40MHz, which is indicated by XCKSEL. + * CLKSTP controls whether the selected clock source gets + * connected to the IrDA block. + * + * On my HP OB-800 the BIOS sets external 40MHz clock as source + * when IrDA enabled and I've never detected any PLL lock success. + * Apparently the 14.3...MHz OSC input required for the PLL to work + * is not connected and the 40MHz EXTCLK is provided externally. + * At least this is what makes the driver working for me. + */ + +enum vlsi_pci_clkctl { + + /* PLL control */ + + CLKCTL_PD_INV = 0x04, /* PD#: inverted power down signal, + * i.e. PLL is powered, if PD_INV set */ + CLKCTL_LOCK = 0x40, /* (ro) set, if PLL is locked */ + + /* clock source selection */ + + CLKCTL_EXTCLK = 0x20, /* set to select external clock input, not PLL */ + CLKCTL_XCKSEL = 0x10, /* set to indicate EXTCLK is 40MHz, not 48MHz */ + + /* IrDA block control */ + + CLKCTL_CLKSTP = 0x80, /* set to disconnect from selected clock source */ + CLKCTL_WAKE = 0x08 /* set to enable wakeup feature: whenever IR activity + * is detected, PD_INV gets set(?) and CLKSTP cleared */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PCI_MSTRPAGE: Master Page Register (u8, rw) and busmastering stuff */ + +#define DMA_MASK_USED_BY_HW 0xffffffff +#define DMA_MASK_MSTRPAGE 0x00ffffff +#define MSTRPAGE_VALUE (DMA_MASK_MSTRPAGE >> 24) + + /* PCI busmastering is somewhat special for this guy - in short: + * + * We select to operate using fixed MSTRPAGE=0, use ISA DMA + * address restrictions to make the PCI BM api aware of this, + * but ensure the hardware is dealing with real 32bit access. + * + * In detail: + * The chip executes normal 32bit busmaster cycles, i.e. + * drives all 32 address lines. These addresses however are + * composed of [0:23] taken from various busaddr-pointers + * and [24:31] taken from the MSTRPAGE register in the VLSI82C147 + * config space. Therefore _all_ busmastering must be + * targeted to/from one single 16MB (busaddr-) superpage! + * The point is to make sure all the allocations for memory + * locations with busmaster access (ring descriptors, buffers) + * are indeed bus-mappable to the same 16MB range (for x86 this + * means they must reside in the same 16MB physical memory address + * range). The only constraint we have which supports "several objects + * mappable to common 16MB range" paradigma, is the old ISA DMA + * restriction to the first 16MB of physical address range. + * Hence the approach here is to enable PCI busmaster support using + * the correct 32bit dma-mask used by the chip. Afterwards the device's + * dma-mask gets restricted to 24bit, which must be honoured somehow by + * all allocations for memory areas to be exposed to the chip ... + * + * Note: + * Don't be surprised to get "Setting latency timer..." messages every + * time when PCI busmastering is enabled for the chip. + * The chip has its PCI latency timer RO fixed at 0 - which is not a + * problem here, because it is never requesting _burst_ transactions. + */ + +/* ------------------------------------------ */ + +/* VLSI_PCIIRMISC: IR Miscellaneous Register (u8, rw) */ + +/* legacy UART emulation - not used by this driver - would require: + * (see below for some register-value definitions) + * + * - IRMISC_UARTEN must be set to enable UART address decoding + * - IRMISC_UARTSEL configured + * - IRCFG_MASTER must be cleared + * - IRCFG_SIR must be set + * - IRENABLE_PHYANDCLOCK must be asserted 0->1 (and hence IRENABLE_SIR_ON) + */ + +enum vlsi_pci_irmisc { + + /* IR transceiver control */ + + IRMISC_IRRAIL = 0x40, /* (ro?) IR rail power indication (and control?) + * 0=3.3V / 1=5V. Probably set during power-on? + * unclear - not touched by driver */ + IRMISC_IRPD = 0x08, /* transceiver power down, if set */ + + /* legacy UART control */ + + IRMISC_UARTTST = 0x80, /* UART test mode - "always write 0" */ + IRMISC_UARTEN = 0x04, /* enable UART address decoding */ + + /* bits [1:0] IRMISC_UARTSEL to select legacy UART address */ + + IRMISC_UARTSEL_3f8 = 0x00, + IRMISC_UARTSEL_2f8 = 0x01, + IRMISC_UARTSEL_3e8 = 0x02, + IRMISC_UARTSEL_2e8 = 0x03 +}; + +/* ================================================================ */ + +/* registers mapped to 32 byte PCI IO space */ + +/* note: better access all registers at the indicated u8/u16 size + * although some of them contain only 1 byte of information. + * some of them (particaluarly PROMPT and IRCFG) ignore + * access when using the wrong addressing mode! + */ + +enum vlsi_pio_regs { + VLSI_PIO_IRINTR = 0x00, /* interrupt enable/request (u8, rw) */ + VLSI_PIO_RINGPTR = 0x02, /* rx/tx ring pointer (u16, ro) */ + VLSI_PIO_RINGBASE = 0x04, /* [23:10] of ring address (u16, rw) */ + VLSI_PIO_RINGSIZE = 0x06, /* rx/tx ring size (u16, rw) */ + VLSI_PIO_PROMPT = 0x08, /* triggers ring processing (u16, wo) */ + /* 0x0a-0x0f: reserved / duplicated UART regs */ + VLSI_PIO_IRCFG = 0x10, /* configuration select (u16, rw) */ + VLSI_PIO_SIRFLAG = 0x12, /* BOF/EOF for filtered SIR (u16, ro) */ + VLSI_PIO_IRENABLE = 0x14, /* enable and status register (u16, rw/ro) */ + VLSI_PIO_PHYCTL = 0x16, /* physical layer current status (u16, ro) */ + VLSI_PIO_NPHYCTL = 0x18, /* next physical layer select (u16, rw) */ + VLSI_PIO_MAXPKT = 0x1a, /* [11:0] max len for packet receive (u16, rw) */ + VLSI_PIO_RCVBCNT = 0x1c /* current receive-FIFO byte count (u16, ro) */ + /* 0x1e-0x1f: reserved / duplicated UART regs */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRINTR: Interrupt Register (u8, rw) */ + +/* enable-bits: + * 1 = enable / 0 = disable + * interrupt condition bits: + * set according to corresponding interrupt source + * (regardless of the state of the enable bits) + * enable bit status indicates whether interrupt gets raised + * write-to-clear + * note: RPKTINT and TPKTINT behave different in legacy UART mode (which we don't use :-) + */ + +enum vlsi_pio_irintr { + IRINTR_ACTEN = 0x80, /* activity interrupt enable */ + IRINTR_ACTIVITY = 0x40, /* activity monitor (traffic detected) */ + IRINTR_RPKTEN = 0x20, /* receive packet interrupt enable*/ + IRINTR_RPKTINT = 0x10, /* rx-packet transfered from fifo to memory finished */ + IRINTR_TPKTEN = 0x08, /* transmit packet interrupt enable */ + IRINTR_TPKTINT = 0x04, /* last bit of tx-packet+crc shifted to ir-pulser */ + IRINTR_OE_EN = 0x02, /* UART rx fifo overrun error interrupt enable */ + IRINTR_OE_INT = 0x01 /* UART rx fifo overrun error (read LSR to clear) */ +}; + +/* we use this mask to check whether the (shared PCI) interrupt is ours */ + +#define IRINTR_INT_MASK (IRINTR_ACTIVITY|IRINTR_RPKTINT|IRINTR_TPKTINT) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGPTR: Ring Pointer Read-Back Register (u16, ro) */ + +/* _both_ ring pointers are indices relative to the _entire_ rx,tx-ring! + * i.e. the referenced descriptor is located + * at RINGBASE + PTR * sizeof(descr) for rx and tx + * therefore, the tx-pointer has offset MAX_RING_DESCR + */ + +#define MAX_RING_DESCR 64 /* tx, rx rings may contain up to 64 descr each */ + +#define RINGPTR_RX_MASK (MAX_RING_DESCR-1) +#define RINGPTR_TX_MASK ((MAX_RING_DESCR-1)<<8) + +#define RINGPTR_GET_RX(p) ((p)&RINGPTR_RX_MASK) +#define RINGPTR_GET_TX(p) (((p)&RINGPTR_TX_MASK)>>8) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGBASE: Ring Pointer Base Address Register (u16, ro) */ + +/* Contains [23:10] part of the ring base (bus-) address + * which must be 1k-alinged. [31:24] is taken from + * VLSI_PCI_MSTRPAGE above. + * The controller initiates non-burst PCI BM cycles to + * fetch and update the descriptors in the ring. + * Once fetched, the descriptor remains cached onchip + * until it gets closed and updated due to the ring + * processing state machine. + * The entire ring area is split in rx and tx areas with each + * area consisting of 64 descriptors of 8 bytes each. + * The rx(tx) ring is located at ringbase+0 (ringbase+64*8). + */ + +#define BUS_TO_RINGBASE(p) (((p)>>10)&0x3fff) + +/* ------------------------------------------ */ + +/* VLSI_PIO_RINGSIZE: Ring Size Register (u16, rw) */ + +/* bit mask to indicate the ring size to be used for rx and tx. + * possible values encoded bits + * 4 0000 + * 8 0001 + * 16 0011 + * 32 0111 + * 64 1111 + * located at [15:12] for tx and [11:8] for rx ([7:0] unused) + * + * note: probably a good idea to have IRCFG_MSTR cleared when writing + * this so the state machines are stopped and the RINGPTR is reset! + */ + +#define SIZE_TO_BITS(num) ((((num)-1)>>2)&0x0f) +#define TX_RX_TO_RINGSIZE(tx,rx) ((SIZE_TO_BITS(tx)<<12)|(SIZE_TO_BITS(rx)<<8)) +#define RINGSIZE_TO_RXSIZE(rs) ((((rs)&0x0f00)>>6)+4) +#define RINGSIZE_TO_TXSIZE(rs) ((((rs)&0xf000)>>10)+4) + + +/* ------------------------------------------ */ + +/* VLSI_PIO_PROMPT: Ring Prompting Register (u16, write-to-start) */ + +/* writing any value kicks the ring processing state machines + * for both tx, rx rings as follows: + * - active rings (currently owning an active descriptor) + * ignore the prompt and continue + * - idle rings fetch the next descr from the ring and start + * their processing + */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRCFG: IR Config Register (u16, rw) */ + +/* notes: + * - not more than one SIR/MIR/FIR bit must be set at any time + * - SIR, MIR, FIR and CRC16 select the configuration which will + * be applied on next 0->1 transition of IRENABLE_PHYANDCLOCK (see below). + * - besides allowing the PCI interface to execute busmaster cycles + * and therefore the ring SM to operate, the MSTR bit has side-effects: + * when MSTR is cleared, the RINGPTR's get reset and the legacy UART mode + * (in contrast to busmaster access mode) gets enabled. + * - clearing ENRX or setting ENTX while data is received may stall the + * receive fifo until ENRX reenabled _and_ another packet arrives + * - SIRFILT means the chip performs the required unwrapping of hardware + * headers (XBOF's, BOF/EOF) and un-escaping in the _receive_ direction. + * Only the resulting IrLAP payload is copied to the receive buffers - + * but with the 16bit FCS still encluded. Question remains, whether it + * was already checked or we should do it before passing the packet to IrLAP? + */ + +enum vlsi_pio_ircfg { + IRCFG_LOOP = 0x4000, /* enable loopback test mode */ + IRCFG_ENTX = 0x1000, /* transmit enable */ + IRCFG_ENRX = 0x0800, /* receive enable */ + IRCFG_MSTR = 0x0400, /* master enable */ + IRCFG_RXANY = 0x0200, /* receive any packet */ + IRCFG_CRC16 = 0x0080, /* 16bit (not 32bit) CRC select for MIR/FIR */ + IRCFG_FIR = 0x0040, /* FIR 4PPM encoding mode enable */ + IRCFG_MIR = 0x0020, /* MIR HDLC encoding mode enable */ + IRCFG_SIR = 0x0010, /* SIR encoding mode enable */ + IRCFG_SIRFILT = 0x0008, /* enable SIR decode filter (receiver unwrapping) */ + IRCFG_SIRTEST = 0x0004, /* allow SIR decode filter when not in SIR mode */ + IRCFG_TXPOL = 0x0002, /* invert tx polarity when set */ + IRCFG_RXPOL = 0x0001 /* invert rx polarity when set */ +}; + +/* ------------------------------------------ */ + +/* VLSI_PIO_SIRFLAG: SIR Flag Register (u16, ro) */ + +/* register contains hardcoded BOF=0xc0 at [7:0] and EOF=0xc1 at [15:8] + * which is used for unwrapping received frames in SIR decode-filter mode + */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_IRENABLE: IR Enable Register (u16, rw/ro) */ + +/* notes: + * - IREN acts as gate for latching the configured IR mode information + * from IRCFG and IRPHYCTL when IREN=reset and applying them when + * IREN gets set afterwards. + * - ENTXST reflects IRCFG_ENTX + * - ENRXST = IRCFG_ENRX && (!IRCFG_ENTX || IRCFG_LOOP) + */ + +enum vlsi_pio_irenable { + IRENABLE_PHYANDCLOCK = 0x8000, /* enable IR phy and gate the mode config (rw) */ + IRENABLE_CFGER = 0x4000, /* mode configuration error (ro) */ + IRENABLE_FIR_ON = 0x2000, /* FIR on status (ro) */ + IRENABLE_MIR_ON = 0x1000, /* MIR on status (ro) */ + IRENABLE_SIR_ON = 0x0800, /* SIR on status (ro) */ + IRENABLE_ENTXST = 0x0400, /* transmit enable status (ro) */ + IRENABLE_ENRXST = 0x0200, /* Receive enable status (ro) */ + IRENABLE_CRC16_ON = 0x0100 /* 16bit (not 32bit) CRC enabled status (ro) */ +}; + +#define IRENABLE_MASK 0xff00 /* Read mask */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_PHYCTL: IR Physical Layer Current Control Register (u16, ro) */ + +/* read-back of the currently applied physical layer status. + * applied from VLSI_PIO_NPHYCTL at rising edge of IRENABLE_PHYANDCLOCK + * contents identical to VLSI_PIO_NPHYCTL (see below) + */ + +/* ------------------------------------------ */ + +/* VLSI_PIO_NPHYCTL: IR Physical Layer Next Control Register (u16, rw) */ + +/* latched during IRENABLE_PHYANDCLOCK=0 and applied at 0-1 transition + * + * consists of BAUD[15:10], PLSWID[9:5] and PREAMB[4:0] bits defined as follows: + * + * SIR-mode: BAUD = (115.2kHz / baudrate) - 1 + * PLSWID = (pulsetime * freq / (BAUD+1)) - 1 + * where pulsetime is the requested IrPHY pulse width + * and freq is 8(16)MHz for 40(48)MHz primary input clock + * PREAMB: don't care for SIR + * + * The nominal SIR pulse width is 3/16 bit time so we have PLSWID=12 + * fixed for all SIR speeds at 40MHz input clock (PLSWID=24 at 48MHz). + * IrPHY also allows shorter pulses down to the nominal pulse duration + * at 115.2kbaud (minus some tolerance) which is 1.41 usec. + * Using the expression PLSWID = 12/(BAUD+1)-1 (multiplied by two for 48MHz) + * we get the minimum acceptable PLSWID values according to the VLSI + * specification, which provides 1.5 usec pulse width for all speeds (except + * for 2.4kbaud getting 6usec). This is fine with IrPHY v1.3 specs and + * reduces the transceiver power which drains the battery. At 9.6kbaud for + * example this amounts to more than 90% battery power saving! + * + * MIR-mode: BAUD = 0 + * PLSWID = 9(10) for 40(48) MHz input clock + * to get nominal MIR pulse width + * PREAMB = 1 + * + * FIR-mode: BAUD = 0 + * PLSWID: don't care + * PREAMB = 15 + */ + +#define PHYCTL_BAUD_SHIFT 10 +#define PHYCTL_BAUD_MASK 0xfc00 +#define PHYCTL_PLSWID_SHIFT 5 +#define PHYCTL_PLSWID_MASK 0x03e0 +#define PHYCTL_PREAMB_SHIFT 0 +#define PHYCTL_PREAMB_MASK 0x001f + +#define PHYCTL_TO_BAUD(bwp) (((bwp)&PHYCTL_BAUD_MASK)>>PHYCTL_BAUD_SHIFT) +#define PHYCTL_TO_PLSWID(bwp) (((bwp)&PHYCTL_PLSWID_MASK)>>PHYCTL_PLSWID_SHIFT) +#define PHYCTL_TO_PREAMB(bwp) (((bwp)&PHYCTL_PREAMB_MASK)>>PHYCTL_PREAMB_SHIFT) + +#define BWP_TO_PHYCTL(b,w,p) ((((b)<0) ? (tmp-1) : 0; +} + +#define PHYCTL_SIR(br,ws,cs) BWP_TO_PHYCTL(BAUD_BITS(br),calc_width_bits((br),(ws),(cs)),0) +#define PHYCTL_MIR(cs) BWP_TO_PHYCTL(0,((cs)?9:10),1) +#define PHYCTL_FIR BWP_TO_PHYCTL(0,0,15) + +/* quite ugly, I know. But implementing these calculations here avoids + * having magic numbers in the code and allows some playing with pulsewidths + * without risk to violate the standards. + * FWIW, here is the table for reference: + * + * baudrate BAUD min-PLSWID nom-PLSWID PREAMB + * 2400 47 0(0) 12(24) 0 + * 9600 11 0(0) 12(24) 0 + * 19200 5 1(2) 12(24) 0 + * 38400 2 3(6) 12(24) 0 + * 57600 1 5(10) 12(24) 0 + * 115200 0 11(22) 12(24) 0 + * MIR 0 - 9(10) 1 + * FIR 0 - 0 15 + * + * note: x(y) means x-value for 40MHz / y-value for 48MHz primary input clock + */ + +/* ------------------------------------------ */ + + +/* VLSI_PIO_MAXPKT: Maximum Packet Length register (u16, rw) */ + +/* maximum acceptable length for received packets */ + +/* hw imposed limitation - register uses only [11:0] */ +#define MAX_PACKET_LENGTH 0x0fff + +/* IrLAP I-field (apparently not defined elsewhere) */ +#define IRDA_MTU 2048 + +/* complete packet consists of A(1)+C(1)+I(<=IRDA_MTU) */ +#define IRLAP_SKB_ALLOCSIZE (1+1+IRDA_MTU) + +/* the buffers we use to exchange frames with the hardware need to be + * larger than IRLAP_SKB_ALLOCSIZE because we may have up to 4 bytes FCS + * appended and, in SIR mode, a lot of frame wrapping bytes. The worst + * case appears to be a SIR packet with I-size==IRDA_MTU and all bytes + * requiring to be escaped to provide transparency. Furthermore, the peer + * might ask for quite a number of additional XBOFs: + * up to 115+48 XBOFS 163 + * regular BOF 1 + * A-field 1 + * C-field 1 + * I-field, IRDA_MTU, all escaped 4096 + * FCS (16 bit at SIR, escaped) 4 + * EOF 1 + * AFAICS nothing in IrLAP guarantees A/C field not to need escaping + * (f.e. 0xc0/0xc1 - i.e. BOF/EOF - are legal values there) so in the + * worst case we have 4269 bytes total frame size. + * However, the VLSI uses 12 bits only for all buffer length values, + * which limits the maximum useable buffer size <= 4095. + * Note this is not a limitation in the receive case because we use + * the SIR filtering mode where the hw unwraps the frame and only the + * bare packet+fcs is stored into the buffer - in contrast to the SIR + * tx case where we have to pass frame-wrapped packets to the hw. + * If this would ever become an issue in real life, the only workaround + * I see would be using the legacy UART emulation in SIR mode. + */ + +#define XFER_BUF_SIZE MAX_PACKET_LENGTH + +/* ------------------------------------------ */ + +/* VLSI_PIO_RCVBCNT: Receive Byte Count Register (u16, ro) */ + +/* receive packet counter gets incremented on every non-filtered + * byte which was put in the receive fifo and reset for each + * new packet. Used to decide whether we are just in the middle + * of receiving + */ + +/* better apply the [11:0] mask when reading, as some docs say the + * reserved [15:12] would return 1 when reading - which is wrong AFAICS + */ +#define RCVBCNT_MASK 0x0fff + +/******************************************************************/ + +/* descriptors for rx/tx ring + * + * accessed by hardware - don't change! + * + * the descriptor is owned by hardware, when the ACTIVE status bit + * is set and nothing (besides reading status to test the bit) + * shall be done. The bit gets cleared by hw, when the descriptor + * gets closed. Premature reaping of descriptors owned be the chip + * can be achieved by disabling IRCFG_MSTR + * + * Attention: Writing addr overwrites status! + * + * ### FIXME: depends on endianess (but there ain't no non-i586 ob800 ;-) + */ + +struct ring_descr_hw { + volatile u16 rd_count; /* tx/rx count [11:0] */ + u16 reserved; + union { + u32 addr; /* [23:0] of the buffer's busaddress */ + struct { + u8 addr_res[3]; + volatile u8 status; /* descriptor status */ + } rd_s __attribute__((packed)); + } rd_u __attribute((packed)); +} __attribute__ ((packed)); + +#define rd_addr rd_u.addr +#define rd_status rd_u.rd_s.status + +/* ring descriptor status bits */ + +#define RD_ACTIVE 0x80 /* descriptor owned by hw (both TX,RX) */ + +/* TX ring descriptor status */ + +#define RD_TX_DISCRC 0x40 /* do not send CRC (for SIR) */ +#define RD_TX_BADCRC 0x20 /* force a bad CRC */ +#define RD_TX_PULSE 0x10 /* send indication pulse after this frame (MIR/FIR) */ +#define RD_TX_FRCEUND 0x08 /* force underrun */ +#define RD_TX_CLRENTX 0x04 /* clear ENTX after this frame */ +#define RD_TX_UNDRN 0x01 /* TX fifo underrun (probably PCI problem) */ + +/* RX ring descriptor status */ + +#define RD_RX_PHYERR 0x40 /* physical encoding error */ +#define RD_RX_CRCERR 0x20 /* CRC error (MIR/FIR) */ +#define RD_RX_LENGTH 0x10 /* frame exceeds buffer length */ +#define RD_RX_OVER 0x08 /* RX fifo overrun (probably PCI problem) */ +#define RD_RX_SIRBAD 0x04 /* EOF missing: BOF follows BOF (SIR, filtered) */ + +#define RD_RX_ERROR 0x7c /* any error in received frame */ + +/* the memory required to hold the 2 descriptor rings */ +#define HW_RING_AREA_SIZE (2 * MAX_RING_DESCR * sizeof(struct ring_descr_hw)) + +/******************************************************************/ + +/* sw-ring descriptors consists of a bus-mapped transfer buffer with + * associated skb and a pointer to the hw entry descriptor + */ + +struct ring_descr { + struct ring_descr_hw *hw; + struct sk_buff *skb; + void *buf; +}; + +/* wrappers for operations on hw-exposed ring descriptors + * access to the hw-part of the descriptors must use these. + */ + +static inline int rd_is_active(struct ring_descr *rd) +{ + return ((rd->hw->rd_status & RD_ACTIVE) != 0); +} + +static inline void rd_activate(struct ring_descr *rd) +{ + rd->hw->rd_status |= RD_ACTIVE; +} + +static inline void rd_set_status(struct ring_descr *rd, u8 s) +{ + rd->hw->rd_status = s; /* may pass ownership to the hardware */ +} + +static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s) +{ + /* order is important for two reasons: + * - overlayed: writing addr overwrites status + * - we want to write status last so we have valid address in + * case status has RD_ACTIVE set + */ + + if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { + ERROR("%s: pci busaddr inconsistency!\n", __FUNCTION__); + dump_stack(); + return; + } + + a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write + * to status - just in case MSTRPAGE_VALUE!=0 + */ + rd->hw->rd_addr = cpu_to_le32(a); + wmb(); + rd_set_status(rd, s); /* may pass ownership to the hardware */ +} + +static inline void rd_set_count(struct ring_descr *rd, u16 c) +{ + rd->hw->rd_count = cpu_to_le16(c); +} + +static inline u8 rd_get_status(struct ring_descr *rd) +{ + return rd->hw->rd_status; +} + +static inline dma_addr_t rd_get_addr(struct ring_descr *rd) +{ + dma_addr_t a; + + a = le32_to_cpu(rd->hw->rd_addr); + return (a & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24); +} + +static inline u16 rd_get_count(struct ring_descr *rd) +{ + return le16_to_cpu(rd->hw->rd_count); +} + +/******************************************************************/ + +/* sw descriptor rings for rx, tx: + * + * operations follow producer-consumer paradigm, with the hw + * in the middle doing the processing. + * ring size must be power of two. + * + * producer advances r->tail after inserting for processing + * consumer advances r->head after removing processed rd + * ring is empty if head==tail / full if (tail+1)==head + */ + +struct vlsi_ring { + struct pci_dev *pdev; + int dir; + unsigned len; + unsigned size; + unsigned mask; + atomic_t head, tail; + struct ring_descr *rd; +}; + +/* ring processing helpers */ + +static inline struct ring_descr *ring_last(struct vlsi_ring *r) +{ + int t; + + t = atomic_read(&r->tail) & r->mask; + return (((t+1) & r->mask) == (atomic_read(&r->head) & r->mask)) ? NULL : &r->rd[t]; +} + +static inline struct ring_descr *ring_put(struct vlsi_ring *r) +{ + atomic_inc(&r->tail); + return ring_last(r); +} + +static inline struct ring_descr *ring_first(struct vlsi_ring *r) +{ + int h; + + h = atomic_read(&r->head) & r->mask; + return (h == (atomic_read(&r->tail) & r->mask)) ? NULL : &r->rd[h]; +} + +static inline struct ring_descr *ring_get(struct vlsi_ring *r) +{ + atomic_inc(&r->head); + return ring_first(r); +} + +/******************************************************************/ + +/* our private compound VLSI-PCI-IRDA device information */ + +typedef struct vlsi_irda_dev { + struct pci_dev *pdev; + struct net_device_stats stats; + + struct irlap_cb *irlap; + + struct qos_info qos; + + unsigned mode; + int baud, new_baud; + + dma_addr_t busaddr; + void *virtaddr; + struct vlsi_ring *tx_ring, *rx_ring; + + struct timeval last_rx; + + spinlock_t lock; + struct semaphore sem; + + u32 cfg_space[64/sizeof(u32)]; + u8 resume_ok; + struct proc_dir_entry *proc_entry; + +} vlsi_irda_dev_t; + +/********************************************************/ + +/* the remapped error flags we use for returning from frame + * post-processing in vlsi_process_tx/rx() after it was completed + * by the hardware. These functions either return the >=0 number + * of transfered bytes in case of success or the negative (-) + * of the or'ed error flags. + */ + +#define VLSI_TX_DROP 0x0001 +#define VLSI_TX_FIFO 0x0002 + +#define VLSI_RX_DROP 0x0100 +#define VLSI_RX_OVER 0x0200 +#define VLSI_RX_LENGTH 0x0400 +#define VLSI_RX_FRAME 0x0800 +#define VLSI_RX_CRC 0x1000 + +/********************************************************/ + +#endif /* IRDA_VLSI_FIR_H */ + diff -Nru a/drivers/net/irda/w83977af.h b/drivers/net/irda/w83977af.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/w83977af.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,53 @@ +#ifndef W83977AF_H +#define W83977AF_H + +#define W977_EFIO_BASE 0x370 +#define W977_EFIO2_BASE 0x3f0 +#define W977_DEVICE_IR 0x06 + + +/* + * Enter extended function mode + */ +static inline void w977_efm_enter(unsigned int efio) +{ + outb(0x87, efio); + outb(0x87, efio); +} + +/* + * Select a device to configure + */ + +static inline void w977_select_device(__u8 devnum, unsigned int efio) +{ + outb(0x07, efio); + outb(devnum, efio+1); +} + +/* + * Write a byte to a register + */ +static inline void w977_write_reg(__u8 reg, __u8 value, unsigned int efio) +{ + outb(reg, efio); + outb(value, efio+1); +} + +/* + * read a byte from a register + */ +static inline __u8 w977_read_reg(__u8 reg, unsigned int efio) +{ + outb(reg, efio); + return inb(efio+1); +} + +/* + * Exit extended function mode + */ +static inline void w977_efm_exit(unsigned int efio) +{ + outb(0xAA, efio); +} +#endif diff -Nru a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c --- a/drivers/net/irda/w83977af_ir.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/irda/w83977af_ir.c Sun Apr 18 13:42:40 2004 @@ -58,8 +58,8 @@ #include #include #include -#include -#include +#include "w83977af.h" +#include "w83977af_ir.h" #ifdef CONFIG_ARCH_NETWINDER /* Adjust to NetWinder differences */ #undef CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */ diff -Nru a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/w83977af_ir.h Sun Apr 18 13:42:40 2004 @@ -0,0 +1,196 @@ +/********************************************************************* + * + * Filename: w83977af_ir.h + * Version: + * Description: + * Status: Experimental. + * Author: Paul VanderSpek + * Created at: Thu Nov 19 13:55:34 1998 + * Modified at: Tue Jan 11 13:08:19 2000 + * Modified by: Dag Brattli + * + * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. + * + * 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. + * + * Neither Dag Brattli nor University of Tromsø admit liability nor + * provide warranty for any of this software. This material is + * provided "AS-IS" and at no charge. + * + ********************************************************************/ + +#ifndef W83977AF_IR_H +#define W83977AF_IR_H + +#include + +/* Flags for configuration register CRF0 */ +#define ENBNKSEL 0x01 +#define APEDCRC 0x02 +#define TXW4C 0x04 +#define RXW4C 0x08 + +/* Bank 0 */ +#define RBR 0x00 /* Receiver buffer register */ +#define TBR 0x00 /* Transmitter buffer register */ + +#define ICR 0x01 /* Interrupt configuration register */ +#define ICR_ERBRI 0x01 /* Receiver buffer register interrupt */ +#define ICR_ETBREI 0x02 /* Transeiver empty interrupt */ +#define ICR_EUSRI 0x04//* IR status interrupt */ +#define ICR_EHSRI 0x04 +#define ICR_ETXURI 0x04 /* Tx underrun */ +#define ICR_EDMAI 0x10 /* DMA interrupt */ +#define ICR_ETXTHI 0x20 /* Transmitter threshold interrupt */ +#define ICR_EFSFI 0x40 /* Frame status FIFO interrupt */ +#define ICR_ETMRI 0x80 /* Timer interrupt */ + +#define UFR 0x02 /* FIFO control register */ +#define UFR_EN_FIFO 0x01 /* Enable FIFO's */ +#define UFR_RXF_RST 0x02 /* Reset Rx FIFO */ +#define UFR_TXF_RST 0x04 /* Reset Tx FIFO */ +#define UFR_RXTL 0x80 /* Rx FIFO threshold (set to 16) */ +#define UFR_TXTL 0x20 /* Tx FIFO threshold (set to 17) */ + +#define ISR 0x02 /* Interrupt status register */ +#define ISR_RXTH_I 0x01 /* Receive threshold interrupt */ +#define ISR_TXEMP_I 0x02 /* Transmitter empty interrupt */ +#define ISR_FEND_I 0x04 +#define ISR_DMA_I 0x10 +#define ISR_TXTH_I 0x20 /* Transmitter threshold interrupt */ +#define ISR_FSF_I 0x40 +#define ISR_TMR_I 0x80 /* Timer interrupt */ + +#define UCR 0x03 /* Uart control register */ +#define UCR_DLS8 0x03 /* 8N1 */ + +#define SSR 0x03 /* Sets select register */ +#define SET0 UCR_DLS8 /* Make sure we keep 8N1 */ +#define SET1 (0x80|UCR_DLS8) /* Make sure we keep 8N1 */ +#define SET2 0xE0 +#define SET3 0xE4 +#define SET4 0xE8 +#define SET5 0xEC +#define SET6 0xF0 +#define SET7 0xF4 + +#define HCR 0x04 +#define HCR_MODE_MASK ~(0xD0) +#define HCR_SIR 0x60 +#define HCR_MIR_576 0x20 +#define HCR_MIR_1152 0x80 +#define HCR_FIR 0xA0 +#define HCR_EN_DMA 0x04 +#define HCR_EN_IRQ 0x08 +#define HCR_TX_WT 0x08 + +#define USR 0x05 /* IR status register */ +#define USR_RDR 0x01 /* Receive data ready */ +#define USR_TSRE 0x40 /* Transmitter empty? */ + +#define AUDR 0x07 +#define AUDR_SFEND 0x08 /* Set a frame end */ +#define AUDR_RXBSY 0x20 /* Rx busy */ +#define AUDR_UNDR 0x40 /* Transeiver underrun */ + +/* Set 2 */ +#define ABLL 0x00 /* Advanced baud rate divisor latch (low byte) */ +#define ABHL 0x01 /* Advanced baud rate divisor latch (high byte) */ + +#define ADCR1 0x02 +#define ADCR1_ADV_SL 0x01 +#define ADCR1_D_CHSW 0x08 /* the specs are wrong. its bit 3, not 4 */ +#define ADCR1_DMA_F 0x02 + +#define ADCR2 0x04 +#define ADCR2_TXFS32 0x01 +#define ADCR2_RXFS32 0x04 + +#define RXFDTH 0x07 + +/* Set 3 */ +#define AUID 0x00 + +/* Set 4 */ +#define TMRL 0x00 /* Timer value register (low byte) */ +#define TMRH 0x01 /* Timer value register (high byte) */ + +#define IR_MSL 0x02 /* Infrared mode select */ +#define IR_MSL_EN_TMR 0x01 /* Enable timer */ + +#define TFRLL 0x04 /* Transmitter frame length (low byte) */ +#define TFRLH 0x05 /* Transmitter frame length (high byte) */ +#define RFRLL 0x06 /* Receiver frame length (low byte) */ +#define RFRLH 0x07 /* Receiver frame length (high byte) */ + +/* Set 5 */ + +#define FS_FO 0x05 /* Frame status FIFO */ +#define FS_FO_FSFDR 0x80 /* Frame status FIFO data ready */ +#define FS_FO_LST_FR 0x40 /* Frame lost */ +#define FS_FO_MX_LEX 0x10 /* Max frame len exceeded */ +#define FS_FO_PHY_ERR 0x08 /* Physical layer error */ +#define FS_FO_CRC_ERR 0x04 +#define FS_FO_RX_OV 0x02 /* Receive overrun */ +#define FS_FO_FSF_OV 0x01 /* Frame status FIFO overrun */ +#define FS_FO_ERR_MSK 0x5f /* Error mask */ + +#define RFLFL 0x06 +#define RFLFH 0x07 + +/* Set 6 */ +#define IR_CFG2 0x00 +#define IR_CFG2_DIS_CRC 0x02 + +/* Set 7 */ +#define IRM_CR 0x07 /* Infrared module control register */ +#define IRM_CR_IRX_MSL 0x40 +#define IRM_CR_AF_MNT 0x80 /* Automatic format */ + +/* For storing entries in the status FIFO */ +struct st_fifo_entry { + int status; + int len; +}; + +struct st_fifo { + struct st_fifo_entry entries[10]; + int head; + int tail; + int len; +}; + +/* Private data for each instance */ +struct w83977af_ir { + struct st_fifo st_fifo; + + int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ + int tx_len; /* Number of frames in tx_buff */ + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + struct qos_info qos; /* QoS capabilities for this device */ + + chipio_t io; /* IrDA controller information */ + iobuff_t tx_buff; /* Transmit buffer */ + iobuff_t rx_buff; /* Receive buffer */ + + /* Note : currently locking is *very* incomplete, but this + * will get you started. Check in nsc-ircc.c for a proper + * locking strategy. - Jean II */ + spinlock_t lock; /* For serializing operations */ + + __u32 new_speed; +}; + +static inline void switch_bank( int iobase, int set) +{ + outb(set, iobase+SSR); +} + +#endif diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h --- a/drivers/net/ixgb/ixgb.h Sun Apr 18 13:42:40 2004 +++ b/drivers/net/ixgb/ixgb.h Sun Apr 18 13:42:40 2004 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -65,8 +66,6 @@ #define BAR_0 0 #define BAR_1 1 #define BAR_5 5 -#define PCI_DMA_64BIT 0xffffffffffffffffULL -#define PCI_DMA_32BIT 0x00000000ffffffffULL #include "ixgb_hw.h" #include "ixgb_ee.h" diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c --- a/drivers/net/ixgb/ixgb_main.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/ixgb/ixgb_main.c Sun Apr 18 13:42:40 2004 @@ -308,10 +308,10 @@ return i; } - if (!(i = pci_set_dma_mask(pdev, PCI_DMA_64BIT))) { + if (!(i = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { pci_using_dac = 1; } else { - if ((i = pci_set_dma_mask(pdev, PCI_DMA_32BIT))) { + if ((i = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) { IXGB_ERR("No usable DMA configuration, aborting\n"); return i; } diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c --- a/drivers/net/natsemi.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/natsemi.c Sun Apr 18 13:42:40 2004 @@ -387,7 +387,7 @@ IntrStatus = 0x10, IntrMask = 0x14, IntrEnable = 0x18, - IntrHoldoff = 0x16, /* DP83816 only */ + IntrHoldoff = 0x1C, /* DP83816 only */ TxRingPtr = 0x20, TxConfig = 0x24, RxRingPtr = 0x30, diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c --- a/drivers/net/pcnet32.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/pcnet32.c Sun Apr 18 13:42:40 2004 @@ -1022,10 +1022,11 @@ * starting until the packet is loaded. Strike one for reliability, lose * one for latency - although on PCI this isnt a big loss. Older chips * have FIFO's smaller than a packet, so you can't do this. + * Turn on BCR18:BurstRdEn and BCR18:BurstWrEn. */ if (fset) { - a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800)); + a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0860)); a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00); dxsuflo = 1; ltint = 1; diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/ppp_generic.c Sun Apr 18 13:42:41 2004 @@ -994,7 +994,11 @@ /* check if we should pass this packet */ /* the filter instructions are constructed assuming a four-byte PPP header on each packet */ - *skb_push(skb, 2) = 1; + { + u_int16_t *p = (u_int16_t *) skb_push(skb, 2); + + *p = htons(4); /* indicate outbound in DLT_LINUX_SLL */; + } if (ppp->pass_filter.filter && sk_run_filter(skb, ppp->pass_filter.filter, ppp->pass_filter.len) == 0) { @@ -1537,7 +1541,11 @@ /* check if the packet passes the pass and active filters */ /* the filter instructions are constructed assuming a four-byte PPP header on each packet */ - *skb_push(skb, 2) = 0; + { + u_int16_t *p = (u_int16_t *) skb_push(skb, 2); + + *p = 0; /* indicate inbound in DLT_LINUX_SLL */ + } if (ppp->pass_filter.filter && sk_run_filter(skb, ppp->pass_filter.filter, ppp->pass_filter.len) == 0) { diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c --- a/drivers/net/sk_mca.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/sk_mca.c Sun Apr 18 13:42:41 2004 @@ -997,13 +997,13 @@ block.Mode &= ~LANCE_INIT_PROM; if (dev->flags & IFF_ALLMULTI) { /* get all multicasts */ - memset(block.LAdrF, 8, 0xff); + memset(block.LAdrF, 0xff, sizeof(block.LAdrF)); } else { /* get selected/no multicasts */ struct dev_mc_list *mptr; int code; - memset(block.LAdrF, 8, 0x00); + memset(block.LAdrF, 0, sizeof(block.LAdrF)); for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) { code = GetHash(mptr->dmi_addr); block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7); diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c --- a/drivers/net/tg3.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/tg3.c Sun Apr 18 13:42:41 2004 @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "2.9" -#define DRV_MODULE_RELDATE "March 8, 2004" +#define DRV_MODULE_VERSION "3.1" +#define DRV_MODULE_RELDATE "April 3, 2004" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -643,7 +643,14 @@ tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200); tg3_writephy(tp, 0x16, 0x0000); - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + /* Set Extended packet length bit for jumbo frames */ + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400); + } + else { + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + } tg3_writephy(tp, MII_TG3_CTRL, phy9_orig); @@ -657,7 +664,7 @@ /* This will reset the tigon3 PHY if there is no valid * link unless the FORCE argument is non-zero. */ -static int tg3_phy_reset(struct tg3 *tp, int force) +static int tg3_phy_reset(struct tg3 *tp) { u32 phy_status; int err; @@ -667,12 +674,6 @@ if (err != 0) return -EBUSY; - /* If we have link, and not forcing a reset, then nothing - * to do. - */ - if ((phy_status & BMSR_LSTATUS) != 0 && (force == 0)) - return 0; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { @@ -699,6 +700,15 @@ tg3_writephy(tp, 0x1c, 0x8d68); tg3_writephy(tp, 0x1c, 0x8d68); } + /* Set Extended packet length bit (bit 14) on all chips that */ + /* support jumbo frames */ + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401 || + (tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411) { + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); + } + else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400); + } tg3_phy_set_wirespeed(tp); return 0; } @@ -1050,6 +1060,8 @@ u32 new_adv; int i; + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400); + if (tp->link_config.phy_is_low_power) { /* Entering low power mode. Disable gigabit and * 100baseT advertisements. @@ -1190,7 +1202,8 @@ int err; /* Turn off tap power management. */ - err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20); + /* Set Extended packet length bit */ + err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); err |= tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x0012); err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x1804); @@ -1212,6 +1225,27 @@ return err; } +static int tg3_copper_is_advertising_all(struct tg3 *tp) +{ + u32 adv_reg, all_mask; + + tg3_readphy(tp, MII_ADVERTISE, &adv_reg); + all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL); + if ((adv_reg & all_mask) != all_mask) + return 0; + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { + u32 tg3_ctrl; + + tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl); + all_mask = (MII_TG3_CTRL_ADV_1000_HALF | + MII_TG3_CTRL_ADV_1000_FULL); + if ((tg3_ctrl & all_mask) != all_mask) + return 0; + } + return 1; +} + static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) { int current_link_up; @@ -1240,7 +1274,7 @@ */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || - tp->pci_chip_rev_id == CHIPREV_ID_5705_A0) && + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) && netif_carrier_ok(tp->dev)) { tg3_readphy(tp, MII_BMSR, &bmsr); tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1248,7 +1282,7 @@ force_reset = 1; } if (force_reset) - tg3_phy_reset(tp, 1); + tg3_phy_reset(tp); if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { tg3_readphy(tp, MII_BMSR, &bmsr); @@ -1275,7 +1309,7 @@ if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 && !(bmsr & BMSR_LSTATUS) && tp->link_config.active_speed == SPEED_1000) { - err = tg3_phy_reset(tp, 1); + err = tg3_phy_reset(tp); if (!err) err = tg3_init_5401phy_dsp(tp); if (err) @@ -1310,8 +1344,14 @@ current_speed = SPEED_INVALID; current_duplex = DUPLEX_INVALID; - tg3_readphy(tp, MII_BMSR, &bmsr); - tg3_readphy(tp, MII_BMSR, &bmsr); + bmsr = 0; + for (i = 0; i < 100; i++) { + tg3_readphy(tp, MII_BMSR, &bmsr); + tg3_readphy(tp, MII_BMSR, &bmsr); + if (bmsr & BMSR_LSTATUS) + break; + udelay(40); + } if (bmsr & BMSR_LSTATUS) { u32 aux_stat, bmcr; @@ -1327,22 +1367,25 @@ tg3_aux_stat_to_speed_duplex(tp, aux_stat, ¤t_speed, ¤t_duplex); - tg3_readphy(tp, MII_BMCR, &bmcr); - tg3_readphy(tp, MII_BMCR, &bmcr); + + bmcr = 0; + for (i = 0; i < 200; i++) { + tg3_readphy(tp, MII_BMCR, &bmcr); + tg3_readphy(tp, MII_BMCR, &bmcr); + if (bmcr && bmcr != 0x7fff) + break; + udelay(10); + } + if (tp->link_config.autoneg == AUTONEG_ENABLE) { if (bmcr & BMCR_ANENABLE) { - u32 gig_ctrl; - current_link_up = 1; /* Force autoneg restart if we are exiting * low power mode. */ - tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl); - if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF | - MII_TG3_CTRL_ADV_1000_FULL))) { + if (!tg3_copper_is_advertising_all(tp)) current_link_up = 0; - } } else { current_link_up = 0; } @@ -2004,6 +2047,13 @@ (6 << TX_LENGTHS_IPG_SHIFT) | (32 << TX_LENGTHS_SLOT_TIME_SHIFT))); + if (netif_carrier_ok(tp->dev)) { + tw32(HOSTCC_STAT_COAL_TICKS, + DEFAULT_STAT_COAL_TICKS); + } else { + tw32(HOSTCC_STAT_COAL_TICKS, 0); + } + return err; } @@ -3398,10 +3448,11 @@ } /* tp->lock is held. */ -static void tg3_chip_reset(struct tg3 *tp) +static int tg3_chip_reset(struct tg3 *tp) { u32 val; u32 flags_save; + int i; if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { /* Force NVRAM to settle. @@ -3469,6 +3520,8 @@ tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); + tw32(GRC_MODE, tp->grc_mode); + if ((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0 && GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { tp->pci_clock_ctrl |= @@ -3476,7 +3529,45 @@ tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl); } - tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); + /* Prevent PXE from restarting. */ + tg3_write_mem(tp, + NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + + if (tp->phy_id == PHY_ID_SERDES) { + tp->mac_mode = MAC_MODE_PORT_MODE_TBI; + tw32_f(MAC_MODE, tp->mac_mode); + } else + tw32_f(MAC_MODE, 0); + udelay(40); + + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { + printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " + "firmware will not restart magic=%08x\n", + tp->dev->name, val); + return -ENODEV; + } + + /* Reprobe ASF enable state. */ + tp->tg3_flags &= ~TG3_FLAG_ENABLE_ASF; + tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); + if (val == NIC_SRAM_DATA_SIG_MAGIC) { + u32 nic_cfg; + + tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); + if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) + tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; + } + + return 0; } /* tp->lock is held. */ @@ -3503,40 +3594,17 @@ /* tp->lock is held. */ static int tg3_halt(struct tg3 *tp) { - u32 val; - int i; + int err; tg3_stop_fw(tp); tg3_abort_hw(tp); - tg3_chip_reset(tp); - tg3_write_mem(tp, - NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { - printk(KERN_ERR PFX "tg3_halt timed out for %s, " - "firmware will not restart magic=%08x\n", - tp->dev->name, val); - return -ENODEV; - } + err = tg3_chip_reset(tp); + if (err) + return err; - if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { - if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) - tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, - DRV_STATE_WOL); - else - tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, - DRV_STATE_UNLOAD); - } else + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, - DRV_STATE_SUSPEND); + DRV_STATE_UNLOAD); return 0; } @@ -4500,36 +4568,9 @@ return err; } - tg3_chip_reset(tp); - - val = tr32(GRC_MODE); - val &= GRC_MODE_HOST_STACKUP; - tw32(GRC_MODE, val | tp->grc_mode); - - tg3_write_mem(tp, - NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); - if (tp->phy_id == PHY_ID_SERDES) { - tp->mac_mode = MAC_MODE_PORT_MODE_TBI; - tw32_f(MAC_MODE, tp->mac_mode); - } else - tw32_f(MAC_MODE, 0); - udelay(40); - - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - if (i >= 100000 && - !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) { - printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " - "firmware will not restart magic=%08x\n", - tp->dev->name, val); - return -ENODEV; - } + err = tg3_chip_reset(tp); + if (err) + return err; if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX, @@ -4552,6 +4593,13 @@ tw32(TG3PCI_PCISTATE, val); } + if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5704_BX) { + /* Enable some hw fixes. */ + val = tr32(TG3PCI_MSI_DATA); + val |= (1 << 26) | (1 << 28) | (1 << 29); + tw32(TG3PCI_MSI_DATA, val); + } + /* Descriptor ring init may make accesses to the * NIC SRAM area to setup the TX descriptors, so we * can only do this after the hardware has been @@ -4582,8 +4630,10 @@ (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP)); /* Setup the timer prescalar register. Clock is always 66Mhz. */ - tw32(GRC_MISC_CFG, - (65 << GRC_MISC_CFG_PRESCALAR_SHIFT)); + val = tr32(GRC_MISC_CFG); + val &= ~0xff; + val |= (65 << GRC_MISC_CFG_PRESCALAR_SHIFT); + tw32(GRC_MISC_CFG, val); /* Initialize MBUF/DESC pool. */ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { @@ -4644,19 +4694,6 @@ return -ENODEV; } - tw32(FTQ_RESET, 0xffffffff); - tw32(FTQ_RESET, 0x00000000); - for (i = 0; i < 2000; i++) { - if (tr32(FTQ_RESET) == 0x00000000) - break; - udelay(10); - } - if (i >= 2000) { - printk(KERN_ERR PFX "tg3_reset_hw cannot reset FTQ for %s.\n", - tp->dev->name); - return -ENODEV; - } - /* Clear statistics/status block in chip, and status block in ram. */ if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) { for (i = NIC_SRAM_STATS_BLK; @@ -4988,8 +5025,17 @@ tw32_f(MAC_RX_MODE, tp->rx_mode); udelay(10); - if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) - tw32(MAC_SERDES_CFG, 0x616000); + if (tp->phy_id == PHY_ID_SERDES) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { + /* Set drive transmission level to 1.2V */ + val = tr32(MAC_SERDES_CFG); + val &= 0xfffff000; + val |= 0x880; + tw32(MAC_SERDES_CFG, val); + } + if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) + tw32(MAC_SERDES_CFG, 0x616000); + } /* Prevent chip from dropping frames when flow control * is enabled. @@ -5882,6 +5928,16 @@ tp->link_config.phy_is_low_power) return -EAGAIN; + if (tp->phy_id == PHY_ID_SERDES) { + /* These are the only valid advertisement bits allowed. */ + if (cmd->autoneg == AUTONEG_ENABLE && + (cmd->advertising & ~(ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_Autoneg | + ADVERTISED_FIBRE))) + return -EINVAL; + } + spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -5891,6 +5947,7 @@ tp->link_config.speed = SPEED_INVALID; tp->link_config.duplex = DUPLEX_INVALID; } else { + tp->link_config.advertising = 0; tp->link_config.speed = cmd->speed; tp->link_config.duplex = cmd->duplex; } @@ -6357,8 +6414,8 @@ { PCI_VENDOR_ID_BROADCOM, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */ { PCI_VENDOR_ID_BROADCOM, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */ { PCI_VENDOR_ID_BROADCOM, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */ - { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */ - { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */ + { PCI_VENDOR_ID_BROADCOM, 0x0009, PHY_ID_BCM5703 }, /* BCM95703Ax1 */ + { PCI_VENDOR_ID_BROADCOM, 0x8009, PHY_ID_BCM5703 }, /* BCM95703Ax2 */ /* 3com boards. */ { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */ @@ -6458,19 +6515,27 @@ tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; } - /* Now read the physical PHY_ID from the chip and verify - * that it is sane. If it doesn't look good, we fall back - * to either the hard-coded table based PHY_ID and failing - * that the value found in the eeprom area. - */ - err = tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1); - err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2); - - hw_phy_id = (hw_phy_id_1 & 0xffff) << 10; - hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16; - hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0; + /* Reading the PHY ID register can conflict with ASF + * firwmare access to the PHY hardware. + */ + err = 0; + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { + hw_phy_id = hw_phy_id_masked = PHY_ID_INVALID; + } else { + /* Now read the physical PHY_ID from the chip and verify + * that it is sane. If it doesn't look good, we fall back + * to either the hard-coded table based PHY_ID and failing + * that the value found in the eeprom area. + */ + err |= tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1); + err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2); + + hw_phy_id = (hw_phy_id_1 & 0xffff) << 10; + hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16; + hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0; - hw_phy_id_masked = hw_phy_id & PHY_ID_MASK; + hw_phy_id_masked = hw_phy_id & PHY_ID_MASK; + } if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) { tp->phy_id = hw_phy_id; @@ -6487,38 +6552,61 @@ } } - err = tg3_phy_reset(tp, 1); - if (err) - return err; + if (tp->phy_id != PHY_ID_SERDES && + !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { + u32 bmsr, adv_reg, tg3_ctrl; - if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || - tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) { - u32 mii_tg3_ctrl; - - /* These chips, when reset, only advertise 10Mb - * capabilities. Fix that. - */ - err = tg3_writephy(tp, MII_ADVERTISE, - (ADVERTISE_CSMA | - ADVERTISE_PAUSE_CAP | - ADVERTISE_10HALF | - ADVERTISE_10FULL | - ADVERTISE_100HALF | - ADVERTISE_100FULL)); - mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF | - MII_TG3_CTRL_ADV_1000_FULL | - MII_TG3_CTRL_AS_MASTER | - MII_TG3_CTRL_ENABLE_AS_MASTER); - if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) - mii_tg3_ctrl = 0; + tg3_readphy(tp, MII_BMSR, &bmsr); + tg3_readphy(tp, MII_BMSR, &bmsr); + + if ((bmsr & BMSR_LSTATUS) && + !(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) + goto skip_phy_reset; + + err = tg3_phy_reset(tp); + if (err) + return err; + + adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL | + ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); + tg3_ctrl = 0; + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { + tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF | + MII_TG3_CTRL_ADV_1000_FULL); + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 || + tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) + tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER | + MII_TG3_CTRL_ENABLE_AS_MASTER); + } + + if (!tg3_copper_is_advertising_all(tp)) { + tg3_writephy(tp, MII_ADVERTISE, adv_reg); - err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl); - err |= tg3_writephy(tp, MII_BMCR, - (BMCR_ANRESTART | BMCR_ANENABLE)); + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) + tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); + + tg3_writephy(tp, MII_BMCR, + BMCR_ANENABLE | BMCR_ANRESTART); + } + tg3_phy_set_wirespeed(tp); + + tg3_writephy(tp, MII_ADVERTISE, adv_reg); + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) + tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl); + } + +skip_phy_reset: + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { + err = tg3_init_5401phy_dsp(tp); + if (err) + return err; } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) { - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00); + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c00); tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f); tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa); } @@ -7738,6 +7826,19 @@ for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); + + printk(KERN_INFO "%s: HostTXDS[%d] RXcsums[%d] LinkChgREG[%d] " + "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " + "TSOcap[%d] \n", + dev->name, + (tp->tg3_flags & TG3_FLAG_HOST_TXDS) != 0, + (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, + (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, + (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, + (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, + (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, + (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, + (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); return 0; diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/via-rhine.c Sun Apr 18 13:42:41 2004 @@ -28,10 +28,10 @@ Linux kernel version history: - + LK1.1.0: - Jeff Garzik: softnet 'n stuff - + LK1.1.1: - Justin Guyett: softnet and locking fixes - Jeff Garzik: use PCI interface @@ -58,7 +58,7 @@ LK1.1.6: - Urban Widmark: merges from Beckers 1.08b version (VT6102 + mdio) set netif_running_on/off on startup, del_timer_sync - + LK1.1.7: - Manfred Spraul: added reset into tx_timeout @@ -83,7 +83,7 @@ LK1.1.13 (jgarzik): - Add ethtool support - Replace some MII-related magic numbers with constants - + LK1.1.14 (Ivan G.): - fixes comments for Rhine-III - removes W_MAX_TIMEOUT (unused) @@ -92,7 +92,7 @@ - sends chip_id as a parameter to wait_for_reset since np is not initialized on first call - changes mmio "else if (chip_id==VT6102)" to "else" so it will work - for Rhine-III's (documentation says same bit is correct) + for Rhine-III's (documentation says same bit is correct) - transmit frame queue message is off by one - fixed - adds IntrNormalSummary to "Something Wicked" exclusion list so normal interrupts will not trigger the message (src: Donald Becker) @@ -316,10 +316,10 @@ The driver runs as two independent, single-threaded flows of control. One is the send-packet routine, which enforces single-threaded use by the -dev->priv->lock spinlock. The other thread is the interrupt handler, which +dev->priv->lock spinlock. The other thread is the interrupt handler, which is single threaded by the hardware and interrupt handling software. -The send packet thread has partial control over the Tx ring. It locks the +The send packet thread has partial control over the Tx ring. It locks the dev->priv->lock whenever it's queuing a Tx packet. If the next slot in the ring is not available it stops the transmit queue by calling netif_stop_queue. @@ -639,7 +639,7 @@ #ifdef USE_MEM long ioaddr0; #endif - + /* when built into the kernel, we only print version if device is found */ #ifndef MODULE static int printed_version; @@ -660,7 +660,7 @@ printk(KERN_ERR "32-bit PCI DMA addresses not supported by the card!?\n"); goto err_out; } - + /* sanity check */ if ((pci_resource_len (pdev, 0) < io_size) || (pci_resource_len (pdev, 1) < io_size)) { @@ -681,7 +681,7 @@ } SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - + if (pci_request_regions(pdev, shortname)) goto err_out_free_netdev; @@ -847,6 +847,8 @@ netif_carrier_on(dev); else netif_carrier_off(dev); + + break; } } np->mii_cnt = phy_idx; @@ -891,7 +893,7 @@ void *ring; dma_addr_t ring_dma; - ring = pci_alloc_consistent(np->pdev, + ring = pci_alloc_consistent(np->pdev, RX_RING_SIZE * sizeof(struct rx_desc) + TX_RING_SIZE * sizeof(struct tx_desc), &ring_dma); @@ -903,7 +905,7 @@ np->tx_bufs = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE, &np->tx_bufs_dma); if (np->tx_bufs == NULL) { - pci_free_consistent(np->pdev, + pci_free_consistent(np->pdev, RX_RING_SIZE * sizeof(struct rx_desc) + TX_RING_SIZE * sizeof(struct tx_desc), ring, ring_dma); @@ -923,7 +925,7 @@ { struct netdev_private *np = dev->priv; - pci_free_consistent(np->pdev, + pci_free_consistent(np->pdev, RX_RING_SIZE * sizeof(struct rx_desc) + TX_RING_SIZE * sizeof(struct tx_desc), np->rx_ring, np->rx_ring_dma); @@ -948,7 +950,7 @@ np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32); np->rx_head_desc = &np->rx_ring[0]; next = np->rx_ring_dma; - + /* Init the ring entries */ for (i = 0; i < RX_RING_SIZE; i++) { np->rx_ring[i].rx_status = 0; @@ -1151,7 +1153,7 @@ if (debug > 1) printk(KERN_DEBUG "%s: via_rhine_open() irq %d.\n", dev->name, np->pdev->irq); - + i = alloc_ring(dev); if (i) return i; @@ -1266,7 +1268,7 @@ /* Reinitialize the hardware. */ wait_for_reset(dev, np->chip_id, dev->name); init_registers(dev); - + spin_unlock(&np->lock); enable_irq(np->pdev->irq); @@ -1316,7 +1318,7 @@ np->tx_ring[entry].addr = cpu_to_le32(np->tx_skbuff_dma[entry]); } - np->tx_ring[entry].desc_length = + np->tx_ring[entry].desc_length = cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); /* lock eth irq */ @@ -1364,7 +1366,7 @@ int handled = 0; ioaddr = dev->base_addr; - + while ((intr_status = get_intr_status(dev))) { handled = 1; @@ -1584,7 +1586,7 @@ break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_skbuff_dma[entry] = - pci_map_single(np->pdev, skb->tail, np->rx_buf_sz, + pci_map_single(np->pdev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->rx_ring[entry].addr = cpu_to_le32(np->rx_skbuff_dma[entry]); } @@ -1892,7 +1894,7 @@ static void __devexit via_rhine_remove_one (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - + unregister_netdev(dev); pci_release_regions(pdev); diff -Nru a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c --- a/drivers/net/wan/lapbether.c Sun Apr 18 13:42:40 2004 +++ b/drivers/net/wan/lapbether.c Sun Apr 18 13:42:40 2004 @@ -392,6 +392,8 @@ /* * Handle device status changes. + * + * Called from notifier with RTNL held. */ static int lapbeth_device_event(struct notifier_block *this, unsigned long event, void *ptr) @@ -402,7 +404,6 @@ if (!dev_is_ethdev(dev)) return NOTIFY_DONE; - rcu_read_lock(); switch (event) { case NETDEV_UP: /* New ethernet device -> new LAPB interface */ @@ -422,7 +423,6 @@ lapbeth_free_device(lapbeth); break; } - rcu_read_unlock(); return NOTIFY_DONE; } diff -Nru a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c --- a/drivers/net/wireless/strip.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/wireless/strip.c Sun Apr 18 13:42:41 2004 @@ -1727,7 +1727,7 @@ sprintf(strip_info->serial_number.c, "%.*s", len, p); } else { printk(KERN_DEBUG - "STRIP: radio serial number shorter (%d) than expected (%d)\n", + "STRIP: radio serial number shorter (%zd) than expected (%d)\n", end - p, len); } } @@ -1745,7 +1745,7 @@ sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr); } else { printk(KERN_DEBUG - "STRIP: radio voltage string shorter (%d) than expected (%d)\n", + "STRIP: radio voltage string shorter (%zd) than expected (%d)\n", end - ptr, len); } } @@ -2330,7 +2330,7 @@ if (*cp == 0x0D) { /* If end of packet, decide what to do with it */ if (strip_info->sx_count > 3000) printk(KERN_INFO - "%s: Cut a %d byte packet (%d bytes remaining)%s\n", + "%s: Cut a %d byte packet (%zd bytes remaining)%s\n", strip_info->dev->name, strip_info->sx_count, end - cp - 1, diff -Nru a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c --- a/drivers/net/zorro8390.c Sun Apr 18 13:42:41 2004 +++ b/drivers/net/zorro8390.c Sun Apr 18 13:42:41 2004 @@ -64,7 +64,7 @@ zorro_id id; const char *name; unsigned int offset; -} cards[] __initdata = { +} cards[] __devinitdata = { { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, }; @@ -150,7 +150,7 @@ while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) if (jiffies - reset_start_time > 2*HZ/100) { - printk(" not found (no reset ack).\n"); + printk(KERN_WARNING " not found (no reset ack).\n"); return -ENODEV; } @@ -233,7 +233,7 @@ return err; } - printk("%s: %s at 0x%08lx, Ethernet Address " + printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address " "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, name, board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); @@ -250,7 +250,7 @@ static int zorro8390_close(struct net_device *dev) { if (ei_debug > 1) - printk("%s: Shutting down ethercard.\n", dev->name); + printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); ei_close(dev); return 0; } @@ -262,7 +262,7 @@ unsigned long reset_start_time = jiffies; if (ei_debug > 1) - printk("resetting the 8390 t=%ld...", jiffies); + printk(KERN_DEBUG "resetting the 8390 t=%ld...\n", jiffies); z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); @@ -272,7 +272,8 @@ /* This check _should_not_ be necessary, omit eventually. */ while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) if (jiffies - reset_start_time > 2*HZ/100) { - printk("%s: ne_reset_8390() did not complete.\n", dev->name); + printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", + dev->name); break; } z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ @@ -291,7 +292,7 @@ /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_get_8390_hdr " + printk(KERN_ERR "%s: DMAing conflict in ne_get_8390_hdr " "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; @@ -332,7 +333,7 @@ /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_block_input " + printk(KERN_ERR "%s: DMAing conflict in ne_block_input " "[DMAstat:%d][irqlock:%d].\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; @@ -372,7 +373,7 @@ /* This *shouldn't* happen. If it does, it's the last thing you'll see */ if (ei_status.dmaing) { - printk("%s: DMAing conflict in ne_block_output." + printk(KERN_ERR "%s: DMAing conflict in ne_block_output." "[DMAstat:%d][irqlock:%d]\n", dev->name, ei_status.dmaing, ei_status.irqlock); return; @@ -398,7 +399,8 @@ while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ - printk("%s: timeout waiting for Tx RDC.\n", dev->name); + printk(KERN_ERR "%s: timeout waiting for Tx RDC.\n", + dev->name); zorro8390_reset_8390(dev); NS8390_init(dev,1); break; diff -Nru a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c --- a/drivers/oprofile/oprofile_stats.c Sun Apr 18 13:42:41 2004 +++ b/drivers/oprofile/oprofile_stats.c Sun Apr 18 13:42:41 2004 @@ -55,7 +55,7 @@ continue; cpu_buf = &cpu_buffer[i]; - snprintf(buf, 6, "cpu%d", i); + snprintf(buf, 10, "cpu%d", i); cpudir = oprofilefs_mkdir(sb, dir, buf); /* Strictly speaking access to these ulongs is racy, diff -Nru a/drivers/pci/Kconfig b/drivers/pci/Kconfig --- a/drivers/pci/Kconfig Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/Kconfig Sun Apr 18 13:42:40 2004 @@ -1,6 +1,25 @@ # # PCI configuration # +config PCI_USE_VECTOR + bool "Vector-based interrupt indexing (MSI)" + depends on (X86_LOCAL_APIC && X86_IO_APIC && !X86_64) || IA64 + default n + help + This replaces the current existing IRQ-based index interrupt scheme + with the vector-base index scheme. The advantages of vector base + over IRQ base are listed below: + 1) Support MSI implementation. + 2) Support future IOxAPIC hotplug + + Note that this allows the device drivers to enable MSI, Message + Signaled Interrupt, on all MSI capable device functions detected. + Message Signal Interrupt enables an MSI-capable hardware device to + send an inbound Memory Write on its PCI bus instead of asserting + IRQ signal on device IRQ pin. + + If you don't know what to do here, say N. + config PCI_LEGACY_PROC bool "Legacy /proc/pci interface" depends on PCI diff -Nru a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c --- a/drivers/pci/hotplug/acpiphp_glue.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/acpiphp_glue.c Sun Apr 18 13:42:40 2004 @@ -1243,40 +1243,38 @@ /** * acpiphp_check_bridge - re-enumerate devices + * + * Iterate over all slots under this bridge and make sure that if a + * card is present they are enabled, and if not they are disabled. */ int acpiphp_check_bridge(struct acpiphp_bridge *bridge) { struct acpiphp_slot *slot; - unsigned int sta; int retval = 0; int enabled, disabled; enabled = disabled = 0; for (slot = bridge->slots; slot; slot = slot->next) { - sta = get_slot_status(slot); + unsigned int status = get_slot_status(slot); if (slot->flags & SLOT_ENABLED) { - /* if enabled but not present, disable */ - if (sta != ACPI_STA_ALL) { - retval = acpiphp_disable_slot(slot); - if (retval) { - err("Error occurred in enabling\n"); - up(&slot->crit_sect); - goto err_exit; - } - disabled++; + if (status == ACPI_STA_ALL) + continue; + retval = acpiphp_disable_slot(slot); + if (retval) { + err("Error occurred in disabling\n"); + goto err_exit; } + disabled++; } else { - /* if disabled but present, enable */ - if (sta == ACPI_STA_ALL) { - retval = acpiphp_enable_slot(slot); - if (retval) { - err("Error occurred in enabling\n"); - up(&slot->crit_sect); - goto err_exit; - } - enabled++; + if (status != ACPI_STA_ALL) + continue; + retval = acpiphp_enable_slot(slot); + if (retval) { + err("Error occurred in enabling\n"); + goto err_exit; } + enabled++; } } diff -Nru a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c --- a/drivers/pci/hotplug/acpiphp_pci.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/acpiphp_pci.c Sun Apr 18 13:42:40 2004 @@ -198,106 +198,42 @@ /* detect_used_resource - subtract resource under dev from bridge */ static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev) { - u32 bar, len; - u64 base; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0 - }; int count; - struct pci_resource *res; dbg("Device %s\n", pci_name(dev)); - for (count = 0; address[count]; count++) { /* for 6 BARs */ - pci_read_config_dword(dev, address[count], &bar); + for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) { + struct pci_resource *res; + struct pci_resource **head; + unsigned long base = dev->resource[count].start; + unsigned long len = dev->resource[count].end - base + 1; + unsigned long flags = dev->resource[count].flags; - if (!bar) /* This BAR is not implemented */ + if (!flags) continue; - pci_write_config_dword(dev, address[count], 0xFFFFFFFF); - pci_read_config_dword(dev, address[count], &len); + dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base, + base + len - 1, flags); - if (len & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - base = bar & 0xFFFFFFFC; - len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource_with_base(&bridge->io_head, base, len); - spin_unlock(&bridge->res_lock); - if (res) - kfree(res); + if (flags & IORESOURCE_IO) { + head = &bridge->io_head; + } else if (flags & IORESOURCE_PREFETCH) { + head = &bridge->p_mem_head; } else { - /* This is Memory */ - base = bar & 0xFFFFFFF0; - if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* pfmem */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ - dbg("prefetch mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1); - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource_with_base(&bridge->p_mem_head, base, len); - spin_unlock(&bridge->res_lock); - if (res) - kfree(res); - } else { - /* regular memory */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { - /* takes up another dword */ - dbg("mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1); - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource_with_base(&bridge->mem_head, base, len); - spin_unlock(&bridge->res_lock); - if (res) - kfree(res); - } + head = &bridge->mem_head; } - pci_write_config_dword(dev, address[count], bar); + spin_lock(&bridge->res_lock); + res = acpiphp_get_resource_with_base(head, base, len); + spin_unlock(&bridge->res_lock); + if (res) + kfree(res); } return 0; } -/* detect_pci_resource_bus - subtract resource under pci_bus */ -static void detect_used_resource_bus(struct acpiphp_bridge *bridge, struct pci_bus *bus) -{ - struct list_head *l; - struct pci_dev *dev; - - list_for_each (l, &bus->devices) { - dev = pci_dev_b(l); - detect_used_resource(bridge, dev); - /* XXX recursive call */ - if (dev->subordinate) - detect_used_resource_bus(bridge, dev->subordinate); - } -} - - /** * acpiphp_detect_pci_resource - detect resources under bridge * @bridge: detect all resources already used under this bridge @@ -306,7 +242,13 @@ */ int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge) { - detect_used_resource_bus(bridge, bridge->pci_bus); + struct list_head *l; + struct pci_dev *dev; + + list_for_each (l, &bridge->pci_bus->devices) { + dev = pci_dev_b(l); + detect_used_resource(bridge, dev); + } return 0; } diff -Nru a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h --- a/drivers/pci/hotplug/pci_hotplug.h Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/pci_hotplug.h Sun Apr 18 13:42:40 2004 @@ -43,7 +43,7 @@ PCI_SPEED_100MHz_PCIX_266 = 0x0a, PCI_SPEED_133MHz_PCIX_266 = 0x0b, PCI_SPEED_66MHz_PCIX_533 = 0x11, - PCI_SPEED_100MHz_PCIX_533 = 0X12, + PCI_SPEED_100MHz_PCIX_533 = 0x12, PCI_SPEED_133MHz_PCIX_533 = 0x13, PCI_SPEED_UNKNOWN = 0xff, }; diff -Nru a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c --- a/drivers/pci/hotplug/pciehp_ctrl.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/pciehp_ctrl.c Sun Apr 18 13:42:40 2004 @@ -135,7 +135,7 @@ p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (!getstatus) { + if (getstatus) { /* * Switch opened */ @@ -1705,7 +1705,7 @@ } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (rc || !getstatus) { + if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); return (0); @@ -1792,7 +1792,7 @@ } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (ret || !getstatus) { + if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); return (0); diff -Nru a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c --- a/drivers/pci/hotplug/pciehp_hpc.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/pciehp_hpc.c Sun Apr 18 13:42:41 2004 @@ -37,6 +37,7 @@ #include #include #include +#include "../pci.h" #include "pciehp.h" #ifdef DEBUG @@ -315,12 +316,13 @@ dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); } - retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd); + dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); + retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE); if (retval) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return retval; } - dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); + dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE); dbg("%s : Exit\n", __FUNCTION__); DBG_LEAVE_ROUTINE @@ -918,13 +920,32 @@ return IRQ_NONE; } - temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00; + dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__); + dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); + temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); if (rc) { err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } + dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); + if (rc) { + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + return IRQ_NONE; + } + dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); + + /* Clear command complete interrupt caused by this write */ + temp_word = 0x1f; + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); + if (rc) { + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + return IRQ_NONE; + } + dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); } if (intr_loc & CMD_COMPLETED) { @@ -949,7 +970,7 @@ hp_slot, php_ctlr->callback_instance_id); /* Clear all events after serving them */ - temp_word = slot_status | 0xff; + temp_word = 0x1F; rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); @@ -963,6 +984,8 @@ return IRQ_NONE; } + dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); + dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); @@ -970,6 +993,23 @@ err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); return IRQ_NONE; } + dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); + + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); + if (rc) { + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + return IRQ_NONE; + } + dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); + + /* Clear command complete interrupt caused by this write */ + temp_word = 0x1F; + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); + if (rc) { + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + return IRQ_NONE; + } + dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); } return IRQ_HANDLED; @@ -1330,7 +1370,7 @@ } dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); - temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x00; + temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); if (rc) { @@ -1346,12 +1386,13 @@ } dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); - rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); + temp_word = 0x1F; /* Clear all events */ + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); if (rc) { err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); goto abort_free_ctlr; } - dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); + dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); if (pciehp_poll_mode) {/* Install interrupt polling code */ /* Install and start the interrupt polling timer */ @@ -1359,15 +1400,16 @@ start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ } else { /* Installs the interrupt handler */ -#ifdef CONFIG_PCI_USE_VECTOR - rc = pci_enable_msi(pdev); - if (rc) { - err("Can't get msi for the hotplug controller\n"); - dbg("%s: rc = %x\n", __FUNCTION__, rc); - goto abort_free_ctlr; + dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk); + if (!pciehp_msi_quirk) { + rc = pci_enable_msi(pdev); + if (rc) { + info("Can't get msi for the hotplug controller\n"); + info("Use INTx for the hotplug controller\n"); + dbg("%s: rc = %x\n", __FUNCTION__, rc); + } else + php_ctlr->irq = pdev->irq; } - php_ctlr->irq = pdev->irq; -#endif rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); if (rc) { @@ -1384,7 +1426,7 @@ dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); intr_enable = ATTN_BUTTN_ENABLE | PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE | - PRSN_DETECT_ENABLE | CMD_CMPL_INTR_ENABLE; + PRSN_DETECT_ENABLE; temp_word = (temp_word & ~intr_enable) | intr_enable; @@ -1402,6 +1444,21 @@ goto abort_free_ctlr; } dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); + rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); + if (rc) { + err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); + goto abort_free_ctlr; + } + dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, + SLOT_STATUS, slot_status); + + temp_word = 0x1F; /* Clear all events */ + rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); + if (rc) { + err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); + goto abort_free_ctlr; + } + dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); /* Add this HPC instance into the HPC list */ spin_lock(&list_lock); diff -Nru a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c --- a/drivers/pci/hotplug/pciehp_pci.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/pciehp_pci.c Sun Apr 18 13:42:41 2004 @@ -192,7 +192,6 @@ for (device = FirstSupported; device <= LastSupported; device++) { ID = 0xFFFFFFFF; rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID); - dbg("%s: ID = %x\n", __FUNCTION__, ID); if (ID != 0xFFFFFFFF) { /* device in slot */ dbg("%s: ID = %x\n", __FUNCTION__, ID); @@ -325,7 +324,6 @@ new_slot->presence_save = 0; new_slot->switch_save = 0; } - dbg("%s: End of For loop\n", __FUNCTION__); } /* End of FOR loop */ dbg("%s: Exit\n", __FUNCTION__); diff -Nru a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c --- a/drivers/pci/hotplug/rpadlpar_core.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/rpadlpar_core.c Sun Apr 18 13:42:41 2004 @@ -79,25 +79,18 @@ return np; } -static inline struct hotplug_slot *find_php_slot(char *drc_name) -{ - struct kobject *k; - - k = kset_find_obj(&pci_hotplug_slots_subsys.kset, drc_name); - if (!k) - return NULL; - - return to_hotplug_slot(k); -} - static struct slot *find_slot(char *drc_name) { - struct hotplug_slot *php_slot = find_php_slot(drc_name); + struct list_head *tmp, *n; + struct slot *slot; - if (!php_slot) - return NULL; + list_for_each_safe(tmp, n, &rpaphp_slot_head) { + slot = list_entry(tmp, struct slot, rpaphp_slot_list); + if (strcmp(slot->location, drc_name) == 0) + return slot; + } - return (struct slot *) php_slot->private; + return NULL; } static void rpadlpar_claim_one_bus(struct pci_bus *b) diff -Nru a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h --- a/drivers/pci/hotplug/rpaphp.h Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/rpaphp.h Sun Apr 18 13:42:40 2004 @@ -85,6 +85,7 @@ u32 type; u32 power_domain; char *name; + char *location; struct device_node *dn; /* slot's device_node in OFDT */ /* dn has phb info */ struct pci_dev *bridge; /* slot's pci_dev in pci_devices */ @@ -129,5 +130,6 @@ extern int register_slot(struct slot *slot); extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); +extern void rpaphp_sysfs_remove_attr_location(struct hotplug_slot *slot); #endif /* _PPC64PHP_H */ diff -Nru a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c --- a/drivers/pci/hotplug/rpaphp_core.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/rpaphp_core.c Sun Apr 18 13:42:41 2004 @@ -246,17 +246,14 @@ int rpaphp_remove_slot(struct slot *slot) { int retval = 0; - char *rm_link; + struct hotplug_slot *php_slot = slot->hotplug_slot; - dbg("%s - Entry: slot[%s]\n", __FUNCTION__, slot->name); - if (slot->dev_type == PCI_DEV) - rm_link = pci_name(slot->bridge); - else - rm_link = strstr(slot->dn->full_name, "@"); - - sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link); list_del(&slot->rpaphp_slot_list); - retval = pci_hp_deregister(slot->hotplug_slot); + + /* remove "php_location" file */ + rpaphp_sysfs_remove_attr_location(php_slot); + + retval = pci_hp_deregister(php_slot); if (retval) err("Problem unregistering a slot %s\n", slot->name); @@ -380,14 +377,7 @@ */ list_for_each_safe(tmp, n, &rpaphp_slot_head) { - char *rm_link; - slot = list_entry(tmp, struct slot, rpaphp_slot_list); - if (slot->dev_type == PCI_DEV) - rm_link = pci_name(slot->bridge); - else - rm_link = strstr(slot->dn->full_name, "@"); - sysfs_remove_link(slot->hotplug_slot->kobj.parent, rm_link); list_del(&slot->rpaphp_slot_list); pci_hp_deregister(slot->hotplug_slot); } @@ -478,3 +468,4 @@ EXPORT_SYMBOL_GPL(rpaphp_add_slot); EXPORT_SYMBOL_GPL(rpaphp_remove_slot); +EXPORT_SYMBOL_GPL(rpaphp_slot_head); diff -Nru a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c --- a/drivers/pci/hotplug/rpaphp_pci.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/rpaphp_pci.c Sun Apr 18 13:42:40 2004 @@ -304,7 +304,6 @@ if (slot->hotplug_slot->info->adapter_status == NOT_VALID) { dbg("%s: NOT_VALID: skip dn->full_name=%s\n", __FUNCTION__, slot->dn->full_name); - dealloc_slot_struct(slot); return (-1); } return (0); diff -Nru a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c --- a/drivers/pci/hotplug/rpaphp_slot.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/rpaphp_slot.c Sun Apr 18 13:42:41 2004 @@ -29,8 +29,36 @@ #include #include "rpaphp.h" -/* free up the memory user by a slot */ +static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) +{ + char *value; + int retval = -ENOENT; + struct slot *slot = (struct slot *)php_slot->private; + + if (!slot) + return retval; + + value = slot->location; + retval = sprintf (buf, "%s\n", value); + return retval; +} +static struct hotplug_slot_attribute hotplug_slot_attr_location = { + .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, + .show = location_read_file, +}; + +static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot) +{ + sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); +} + +void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) +{ + sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); +} + +/* free up the memory user by a slot */ static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot? (struct slot *) hotplug_slot->private:NULL; @@ -76,17 +104,25 @@ return (NULL); } memset(slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); - slot->hotplug_slot->name = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); + slot->hotplug_slot->name = kmalloc(BUS_ID_SIZE + 1, GFP_KERNEL); if (!slot->hotplug_slot->name) { kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); kfree(slot); return (NULL); } + slot->location = kmalloc(strlen(drc_name) + 1, GFP_KERNEL); + if (!slot->location) { + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); + return (NULL); + } slot->name = slot->hotplug_slot->name; slot->dn = dn; slot->index = drc_index; - strcpy(slot->name, drc_name); + strcpy(slot->location, drc_name); slot->power_domain = power_domain; slot->magic = SLOT_MAGIC; slot->hotplug_slot->private = slot; @@ -110,41 +146,9 @@ rpaphp_release_slot(slot->hotplug_slot); return (retval); } - switch (slot->dev_type) { - case PCI_DEV: - /* create symlink between slot->name and it's bus_id */ - - dbg("%s: sysfs_create_link: %s --> %s\n", __FUNCTION__, - pci_name(slot->bridge), slot->name); - - retval = sysfs_create_link(slot->hotplug_slot->kobj.parent, - &slot->hotplug_slot->kobj, - pci_name(slot->bridge)); - if (retval) { - err("sysfs_create_link failed with error %d\n", retval); - rpaphp_release_slot(slot->hotplug_slot); - return (retval); - } - break; - case VIO_DEV: - /* create symlink between slot->name and it's uni-address */ - vio_uni_addr = strchr(slot->dn->full_name, '@'); - if (!vio_uni_addr) - return (1); - dbg("%s: sysfs_create_link: %s --> %s\n", __FUNCTION__, - vio_uni_addr, slot->name); - retval = sysfs_create_link(slot->hotplug_slot->kobj.parent, - &slot->hotplug_slot->kobj, - vio_uni_addr); - if (retval) { - err("sysfs_create_link failed with error %d\n", retval); - rpaphp_release_slot(slot->hotplug_slot); - return (retval); - } - break; - default: - return (1); - } + + /* create "phy_locatoin" file */ + rpaphp_sysfs_add_attr_location(slot->hotplug_slot); /* add slot to our internal list */ dbg("%s adding slot[%s] to rpaphp_slot_list\n", diff -Nru a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c --- a/drivers/pci/hotplug/shpchp_ctrl.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/hotplug/shpchp_ctrl.c Sun Apr 18 13:42:41 2004 @@ -138,7 +138,7 @@ p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (!getstatus) { + if (getstatus) { /* * Switch opened */ @@ -1219,7 +1219,7 @@ up(&ctrl->crit_sect); } } else { - if ((bus_speed > 0x4) || (max_bus_speed > 0x4)) { + if (bus_speed > 0x4) { err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); return WRONG_BUS_FREQUENCY; } @@ -1302,7 +1302,7 @@ up(&ctrl->crit_sect); } } else { - if ((bus_speed > 0x2) || (max_bus_speed > 0x2)) { + if (bus_speed > 0x2) { err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed); return WRONG_BUS_FREQUENCY; } @@ -2107,7 +2107,7 @@ return (0); } rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (rc || !getstatus) { + if (rc || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); return (0); @@ -2192,7 +2192,7 @@ return (0); } ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - if (ret || !getstatus) { + if (ret || getstatus) { info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); up(&p_slot->ctrl->crit_sect); return (0); diff -Nru a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c --- a/drivers/pci/hotplug/shpchp_hpc.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/shpchp_hpc.c Sun Apr 18 13:42:40 2004 @@ -104,12 +104,12 @@ #define PCIX_66MHZ_ECC 0x5 #define PCIX_100MHZ_ECC 0x6 #define PCIX_133MHZ_ECC 0x7 -#define PCIX_66MHZ_266 0x8 -#define PCIX_100MHZ_266 0x9 -#define PCIX_133MHZ_266 0x0a -#define PCIX_66MHZ_533 0x0b -#define PCIX_100MHZ_533 0x0c -#define PCIX_133MHZ_533 0x0d +#define PCIX_66MHZ_266 0x9 +#define PCIX_100MHZ_266 0xa +#define PCIX_133MHZ_266 0xb +#define PCIX_66MHZ_533 0x11 +#define PCIX_100MHZ_533 0x12 +#define PCIX_133MHZ_533 0x13 /* Slot Configuration */ #define SLOT_NUM 0x0000001F @@ -464,7 +464,8 @@ slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); slot_status = (u16)slot_reg; - *status = ((slot_status & 0x0100) == 0) ? 1 : 0; + *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */ + DBG_LEAVE_ROUTINE return 0; @@ -1441,6 +1442,7 @@ err("%s : shpc_cap_offset == 0\n", __FUNCTION__); goto abort_free_ctlr; } + dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset); rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET); if (rc) { @@ -1547,15 +1549,13 @@ start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ } else { /* Installs the interrupt handler */ -#ifdef CONFIG_PCI_USE_VECTOR rc = pci_enable_msi(pdev); if (rc) { - err("Can't get msi for the hotplug controller\n"); + info("Can't get msi for the hotplug controller\n"); + info("Use INTx for the hotplug controller\n"); dbg("%s: rc = %x\n", __FUNCTION__, rc); - goto abort_free_ctlr; - } - php_ctlr->irq = pdev->irq; -#endif + } else + php_ctlr->irq = pdev->irq; rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); diff -Nru a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c --- a/drivers/pci/hotplug/shpchprm_acpi.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/shpchprm_acpi.c Sun Apr 18 13:42:40 2004 @@ -1267,7 +1267,8 @@ int shpchprm_print_pirt(void) { dbg("SHPCHPRM ACPI Slots\n"); - print_acpi_resources (acpi_bridges_head); + if (acpi_bridges_head) + print_acpi_resources (acpi_bridges_head); return 0; } diff -Nru a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c --- a/drivers/pci/hotplug/shpchprm_legacy.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/hotplug/shpchprm_legacy.c Sun Apr 18 13:42:40 2004 @@ -96,23 +96,6 @@ return fp; } -#if link_available -/* - * Links available memory, IO, and IRQ resources for programming - * devices which may be added to the system - * - * Returns 0 if success - */ -static int -link_available_resources ( - struct controller *ctrl, - struct pci_func *func, - int index ) -{ - return shpchp_save_used_resources (ctrl, func, !DISABLE_CARD); -} -#endif - /* * shpchprm_find_available_resources * @@ -345,19 +328,6 @@ } } -#if link_available - ++index; - - while (index < 8) { - if (((func = shpchp_slot_find(primary_bus, dev_func >> 3, index)) != NULL) && populated_slot) - rc = link_available_resources(ctrl, func, index); - - if (rc) - break; - - ++index; - } -#endif i--; one_slot += sizeof(struct slot_rt); } diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c --- a/drivers/pci/pci-sysfs.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/pci-sysfs.c Sun Apr 18 13:42:41 2004 @@ -1,8 +1,8 @@ /* * drivers/pci/pci-sysfs.c * - * (C) Copyright 2002 Greg Kroah-Hartman - * (C) Copyright 2002 IBM Corp. + * (C) Copyright 2002-2004 Greg Kroah-Hartman + * (C) Copyright 2002-2004 IBM Corp. * (C) Copyright 2003 Matthew Wilcox * (C) Copyright 2003 Hewlett-Packard * @@ -71,7 +71,7 @@ /* Several chips lock up trying to read undefined config space */ if (capable(CAP_SYS_ADMIN)) { - size = 256; + size = dev->cfg_size; } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { size = 128; } @@ -123,10 +123,10 @@ unsigned int size = count; loff_t init_off = off; - if (off > 256) + if (off > dev->cfg_size) return 0; - if (off + count > 256) { - size = 256 - off; + if (off + count > dev->cfg_size) { + size = dev->cfg_size - off; count = size; } @@ -167,6 +167,17 @@ .write = pci_write_config, }; +static struct bin_attribute pcie_config_attr = { + .attr = { + .name = "config", + .mode = S_IRUGO | S_IWUSR, + .owner = THIS_MODULE, + }, + .size = 4096, + .read = pci_read_config, + .write = pci_write_config, +}; + void pci_create_sysfs_dev_files (struct pci_dev *pdev) { struct device *dev = &pdev->dev; @@ -179,7 +190,11 @@ device_create_file (dev, &dev_attr_class); device_create_file (dev, &dev_attr_irq); device_create_file (dev, &dev_attr_resource); - sysfs_create_bin_file(&dev->kobj, &pci_config_attr); + + if (pdev->cfg_size < 4096) + sysfs_create_bin_file(&dev->kobj, &pci_config_attr); + else + sysfs_create_bin_file(&dev->kobj, &pcie_config_attr); /* add platform-specific attributes */ pcibios_add_platform_entries(pdev); diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/pci.c Sun Apr 18 13:42:40 2004 @@ -111,21 +111,15 @@ * support it. Possible values for @cap: * * %PCI_CAP_ID_PM Power Management - * * %PCI_CAP_ID_AGP Accelerated Graphics Port - * * %PCI_CAP_ID_VPD Vital Product Data - * * %PCI_CAP_ID_SLOTID Slot Identification - * * %PCI_CAP_ID_MSI Message Signalled Interrupts - * * %PCI_CAP_ID_CHSWP CompactPCI HotSwap - * * %PCI_CAP_ID_PCIX PCI-X + * %PCI_CAP_ID_EXP PCI Express */ -int -pci_find_capability(struct pci_dev *dev, int cap) +int pci_find_capability(struct pci_dev *dev, int cap) { return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap); } @@ -153,6 +147,54 @@ } /** + * pci_find_ext_capability - Find an extended capability + * @dev: PCI device to query + * @cap: capability code + * + * Returns the address of the requested extended capability structure + * within the device's PCI configuration space or 0 if the device does + * not support it. Possible values for @cap: + * + * %PCI_EXT_CAP_ID_ERR Advanced Error Reporting + * %PCI_EXT_CAP_ID_VC Virtual Channel + * %PCI_EXT_CAP_ID_DSN Device Serial Number + * %PCI_EXT_CAP_ID_PWR Power Budgeting + */ +int pci_find_ext_capability(struct pci_dev *dev, int cap) +{ + u32 header; + int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */ + int pos = 0x100; + + if (dev->cfg_size <= 256) + return 0; + + if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) + return 0; + + /* + * If we have no capabilities, this is indicated by cap ID, + * cap version and next pointer all being 0. + */ + if (header == 0) + return 0; + + while (ttl-- > 0) { + if (PCI_EXT_CAP_ID(header) == cap) + return pos; + + pos = PCI_EXT_CAP_NEXT(header); + if (pos < 0x100) + break; + + if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) + break; + } + + return 0; +} + +/** * pci_find_parent_resource - return resource region of parent bus of given region * @dev: PCI device structure contains resources to be searched * @res: child resource record for which parent is sought @@ -658,6 +700,10 @@ } } +#ifndef HAVE_ARCH_PCI_SET_DMA_MASK +/* + * These can be overridden by arch-specific implementations + */ int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { @@ -690,6 +736,7 @@ return 0; } +#endif static int __devinit pci_init(void) { diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h --- a/drivers/pci/pci.h Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/pci.h Sun Apr 18 13:42:40 2004 @@ -60,3 +60,5 @@ /* Lock for read/write access to pci device and bus lists */ extern spinlock_t pci_bus_lock; + +extern int pciehp_msi_quirk; diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c --- a/drivers/pci/probe.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/probe.c Sun Apr 18 13:42:41 2004 @@ -18,6 +18,8 @@ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 +#define PCI_CFG_SPACE_SIZE 256 +#define PCI_CFG_SPACE_EXP_SIZE 4096 /* Ugh. Need to stop exporting this to modules. */ LIST_HEAD(pci_root_buses); @@ -530,6 +532,43 @@ kfree(pci_dev); } +/** + * pci_cfg_space_size - get the configuration space size of the PCI device. + * + * Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices + * have 4096 bytes. Even if the device is capable, that doesn't mean we can + * access it. Maybe we don't have a way to generate extended config space + * accesses, or the device is behind a reverse Express bridge. So we try + * reading the dword at 0x100 which must either be 0 or a valid extended + * capability header. + */ +static int pci_cfg_space_size(struct pci_dev *dev) +{ + int pos; + u32 status; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) { + pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); + if (!pos) + goto fail; + + pci_read_config_dword(dev, pos + PCI_X_STATUS, &status); + if (!(status & (PCI_X_STATUS_266MHZ | PCI_X_STATUS_533MHZ))) + goto fail; + } + + if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) + goto fail; + if (status == 0xffffffff) + goto fail; + + return PCI_CFG_SPACE_EXP_SIZE; + + fail: + return PCI_CFG_SPACE_SIZE; +} + /* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... @@ -566,6 +605,7 @@ dev->multifunction = !!(hdr_type & 0x80); dev->vendor = l & 0xffff; dev->device = (l >> 16) & 0xffff; + dev->cfg_size = pci_cfg_space_size(dev); /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ diff -Nru a/drivers/pci/proc.c b/drivers/pci/proc.c --- a/drivers/pci/proc.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pci/proc.c Sun Apr 18 13:42:41 2004 @@ -16,16 +16,15 @@ #include #include -#define PCI_CFG_SPACE_SIZE 256 - static int proc_initialized; /* = 0 */ static loff_t proc_bus_pci_lseek(struct file *file, loff_t off, int whence) { loff_t new = -1; + struct inode *inode = file->f_dentry->d_inode; - down(&file->f_dentry->d_inode->i_sem); + down(&inode->i_sem); switch (whence) { case 0: new = off; @@ -34,14 +33,14 @@ new = file->f_pos + off; break; case 2: - new = PCI_CFG_SPACE_SIZE + off; + new = inode->i_size + off; break; } - if (new < 0 || new > PCI_CFG_SPACE_SIZE) + if (new < 0 || new > inode->i_size) new = -EINVAL; else file->f_pos = new; - up(&file->f_dentry->d_inode->i_sem); + up(&inode->i_sem); return new; } @@ -61,7 +60,7 @@ */ if (capable(CAP_SYS_ADMIN)) - size = PCI_CFG_SPACE_SIZE; + size = dev->cfg_size; else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) size = 128; else @@ -134,14 +133,15 @@ const struct proc_dir_entry *dp = PDE(ino); struct pci_dev *dev = dp->data; int pos = *ppos; + int size = dev->cfg_size; int cnt; - if (pos >= PCI_CFG_SPACE_SIZE) + if (pos >= size) return 0; - if (nbytes >= PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE; - if (pos + nbytes > PCI_CFG_SPACE_SIZE) - nbytes = PCI_CFG_SPACE_SIZE - pos; + if (nbytes >= size) + nbytes = size; + if (pos + nbytes > size) + nbytes = size - pos; cnt = nbytes; if (!access_ok(VERIFY_READ, buf, cnt)) @@ -403,7 +403,7 @@ return -ENOMEM; e->proc_fops = &proc_bus_pci_operations; e->data = dev; - e->size = PCI_CFG_SPACE_SIZE; + e->size = dev->cfg_size; return 0; } diff -Nru a/drivers/pci/quirks.c b/drivers/pci/quirks.c --- a/drivers/pci/quirks.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pci/quirks.c Sun Apr 18 13:42:40 2004 @@ -868,6 +868,13 @@ } #endif /* CONFIG_SCSI_SATA */ +int pciehp_msi_quirk; + +static void __devinit quirk_pciehp_msi(struct pci_dev *pdev) +{ + pciehp_msi_quirk = 1; +} + /* * The main table of quirks. * @@ -984,6 +991,8 @@ quirk_intel_ide_combined }, #endif /* CONFIG_SCSI_SATA */ + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SMCH, quirk_pciehp_msi }, + { 0 } }; @@ -1008,3 +1017,5 @@ pci_do_fixups(dev, pass, pcibios_fixups); pci_do_fixups(dev, pass, pci_fixups); } + +EXPORT_SYMBOL(pciehp_msi_quirk); diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c --- a/drivers/pcmcia/cistpl.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pcmcia/cistpl.c Sun Apr 18 13:42:40 2004 @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -78,7 +79,7 @@ /* Parameters that can be set with 'insmod' */ -#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c --- a/drivers/pcmcia/cs.c Sun Apr 18 13:42:40 2004 +++ b/drivers/pcmcia/cs.c Sun Apr 18 13:42:40 2004 @@ -94,7 +94,7 @@ MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS); MODULE_LICENSE("Dual MPL/GPL"); -#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) INT_MODULE_PARM(setup_delay, 10); /* centiseconds */ INT_MODULE_PARM(resume_delay, 20); /* centiseconds */ diff -Nru a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c --- a/drivers/pcmcia/i82365.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pcmcia/i82365.c Sun Apr 18 13:42:41 2004 @@ -104,7 +104,8 @@ static int ignore = -1; /* Bit map or list of interrupts to choose from */ static u_int irq_mask = 0xffff; -static int irq_list[16] = { -1 }; +static int irq_list[16]; +static int irq_list_count; /* The card status change interrupt -- 0 means autoselect */ static int cs_irq = 0; @@ -130,27 +131,27 @@ static int cable_mode = -1; static int wakeup = 0; -MODULE_PARM(i365_base, "i"); -MODULE_PARM(ignore, "i"); -MODULE_PARM(extra_sockets, "i"); -MODULE_PARM(irq_mask, "i"); -MODULE_PARM(irq_list, "1-16i"); -MODULE_PARM(cs_irq, "i"); -MODULE_PARM(async_clock, "i"); -MODULE_PARM(cable_mode, "i"); -MODULE_PARM(wakeup, "i"); - -MODULE_PARM(do_scan, "i"); -MODULE_PARM(poll_interval, "i"); -MODULE_PARM(cycle_time, "i"); -MODULE_PARM(has_dma, "i"); -MODULE_PARM(has_led, "i"); -MODULE_PARM(has_ring, "i"); -MODULE_PARM(dynamic_mode, "i"); -MODULE_PARM(freq_bypass, "i"); -MODULE_PARM(setup_time, "i"); -MODULE_PARM(cmd_time, "i"); -MODULE_PARM(recov_time, "i"); +module_param(i365_base, int, 0444); +module_param(ignore, int, 0444); +module_param(extra_sockets, int, 0444); +module_param(irq_mask, int, 0444); +module_param_array(irq_list, int, irq_list_count, 0444); +module_param(cs_irq, int, 0444); +module_param(async_clock, int, 0444); +module_param(cable_mode, int, 0444); +module_param(wakeup, int, 0444); + +module_param(do_scan, int, 0444); +module_param(poll_interval, int, 0444); +module_param(cycle_time, int, 0444); +module_param(has_dma, int, 0444); +module_param(has_led, int, 0444); +module_param(has_ring, int, 0444); +module_param(dynamic_mode, int, 0444); +module_param(freq_bypass, int, 0444); +module_param(setup_time, int, 0444); +module_param(cmd_time, int, 0444); +module_param(recov_time, int, 0444); /*====================================================================*/ @@ -705,10 +706,10 @@ printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : "")); /* Set host options, build basic interrupt mask */ - if (irq_list[0] == -1) + if (irq_list_count == 0) mask = irq_mask; else - for (i = mask = 0; i < 16; i++) + for (i = mask = 0; i < irq_list_count; i++) mask |= (1< #include +#include #include #include #include @@ -56,7 +57,7 @@ /* Parameters that can be set with 'insmod' */ -#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) INT_MODULE_PARM(probe_mem, 1); /* memory probe? */ #ifdef CONFIG_PCMCIA_PROBE diff -Nru a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c --- a/drivers/pcmcia/tcic.c Sun Apr 18 13:42:41 2004 +++ b/drivers/pcmcia/tcic.c Sun Apr 18 13:42:41 2004 @@ -60,7 +60,6 @@ static int pc_debug; module_param(pc_debug, int, 0644); -MODULE_PARM(pc_debug, "i"); static const char *version = "tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)"; @@ -91,7 +90,8 @@ /* Bit map of interrupts to choose from */ static u_int irq_mask = 0xffff; -static int irq_list[16] = { -1 }; +static int irq_list[16]; +static int irq_list_count; /* The card status change interrupt -- 0 means autoselect */ static int cs_irq; @@ -105,15 +105,15 @@ /* CCLK external clock time, in nanoseconds. 70 ns = 14.31818 MHz */ static int cycle_time = 70; -MODULE_PARM(tcic_base, "i"); -MODULE_PARM(ignore, "i"); -MODULE_PARM(do_scan, "i"); -MODULE_PARM(irq_mask, "i"); -MODULE_PARM(irq_list, "1-16i"); -MODULE_PARM(cs_irq, "i"); -MODULE_PARM(poll_interval, "i"); -MODULE_PARM(poll_quick, "i"); -MODULE_PARM(cycle_time, "i"); +module_param(tcic_base, int, 0444); +module_param(ignore, int, 0444); +module_param(do_scan, int, 0444); +module_param(irq_mask, int, 0444); +module_param_array(irq_list, int, irq_list_count, 0444); +module_param(cs_irq, int, 0444); +module_param(poll_interval, int, 0444); +module_param(poll_quick, int, 0444); +module_param(cycle_time, int, 0444); /*====================================================================*/ @@ -481,10 +481,10 @@ /* Build interrupt mask */ printk(", %d sockets\n" KERN_INFO " irq list (", sockets); - if (irq_list[0] == -1) + if (irq_list_count == 0) mask = irq_mask; else - for (i = mask = 0; i < 16; i++) + for (i = mask = 0; i < irq_list_count; i++) mask |= (1<scsicmd = NULL; qc->ap = ap; qc->dev = dev; + qc->cursect = qc->cursg = qc->cursg_ofs = 0; INIT_LIST_HEAD(&qc->node); init_MUTEX_LOCKED(&qc->sem); diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c --- a/drivers/scsi/libata-scsi.c Sun Apr 18 13:42:40 2004 +++ b/drivers/scsi/libata-scsi.c Sun Apr 18 13:42:40 2004 @@ -32,6 +32,7 @@ #include "libata.h" +typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd); static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -222,7 +223,6 @@ struct ata_taskfile *tf = &qc->tf; unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; - qc->cursect = qc->cursg = qc->cursg_ofs = 0; tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->hob_nsect = 0; tf->hob_lbal = 0; @@ -335,7 +335,8 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) + void (*done)(struct scsi_cmnd *), + ata_xlat_func_t xlat_func) { struct ata_queued_cmd *qc; u8 *scsicmd = cmd->cmnd; @@ -352,9 +353,11 @@ if (!qc) return; - qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ + if (cmd->sc_data_direction == SCSI_DATA_READ || + cmd->sc_data_direction == SCSI_DATA_WRITE) + qc->flags |= ATA_QCFLAG_SG; /* data is present; dma-map it */ - if (ata_scsi_rw_xlat(qc, scsicmd)) + if (xlat_func(qc, scsicmd)) goto err_out; /* select device, send command to hardware */ @@ -1014,17 +1017,17 @@ } /** - * ata_scsi_xlat_possible - check if SCSI to ATA translation is possible + * ata_get_xlat_func - check if SCSI to ATA translation is possible * @cmd: SCSI command opcode to consider * * Look up the SCSI command given, and determine whether the * SCSI command is to be translated or simulated. * * RETURNS: - * Non-zero if possible, zero if not. + * Pointer to translation function if possible, %NULL if not. */ -static inline int ata_scsi_xlat_possible(u8 cmd) +static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd) { switch (cmd) { case READ_6: @@ -1034,10 +1037,10 @@ case WRITE_6: case WRITE_10: case WRITE_16: - return 1; + return ata_scsi_rw_xlat; } - return 0; + return NULL; } /** @@ -1099,8 +1102,10 @@ } if (dev->class == ATA_DEV_ATA) { - if (ata_scsi_xlat_possible(cmd->cmnd[0])) - ata_scsi_translate(ap, dev, cmd, done); + ata_xlat_func_t xlat_func = ata_get_xlat_func(cmd->cmnd[0]); + + if (xlat_func) + ata_scsi_translate(ap, dev, cmd, done, xlat_func); else ata_scsi_simulate(ap, dev, cmd, done); } else diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c --- a/drivers/scsi/sata_promise.c Sun Apr 18 13:42:41 2004 +++ b/drivers/scsi/sata_promise.c Sun Apr 18 13:42:41 2004 @@ -1180,14 +1180,14 @@ static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol != ATA_PROT_DMA) + if (tf->protocol == ATA_PROT_PIO) ata_tf_load_mmio(ap, tf); } static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) { - if (tf->protocol != ATA_PROT_DMA) + if (tf->protocol == ATA_PROT_PIO) ata_exec_command_mmio(ap, tf); } diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c --- a/drivers/serial/8250.c Sun Apr 18 13:42:40 2004 +++ b/drivers/serial/8250.c Sun Apr 18 13:42:40 2004 @@ -21,6 +21,7 @@ */ #include #include +#include #include #include #include @@ -117,11 +118,11 @@ #define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) -#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE) +#ifdef CONFIG_SERIAL_8250_RSA #define PORT_RSA_MAX 4 -static int probe_rsa[PORT_RSA_MAX]; -static int force_rsa[PORT_RSA_MAX]; +static unsigned long probe_rsa[PORT_RSA_MAX]; +static unsigned int probe_rsa_count; #endif /* CONFIG_SERIAL_8250_RSA */ struct uart_8250_port { @@ -678,21 +679,16 @@ break; } -#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE) +#ifdef CONFIG_SERIAL_8250_RSA /* * Only probe for RSA ports if we got the region. */ if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) { int i; - for (i = 0 ; i < PORT_RSA_MAX ; ++i) { - if (!probe_rsa[i] && !force_rsa[i]) - break; - if (((probe_rsa[i] != up->port.iobase) || - check_region(up->port.iobase + UART_RSA_BASE, 16)) && - (force_rsa[i] != up->port.iobase)) - continue; - if (__enable_rsa(up)) { + for (i = 0 ; i < probe_rsa_count; ++i) { + if (probe_rsa[i] == up->port.iobase && + __enable_rsa(up)) { up->port.type = PORT_RSA; break; } @@ -2215,14 +2211,12 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $"); -MODULE_PARM(share_irqs, "i"); +module_param(share_irqs, uint, 0644); MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" " (unsafe)"); -#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE) -MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); +#ifdef CONFIG_SERIAL_8250_RSA +module_param_array(probe_rsa, ulong, probe_rsa_count, 0444); MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); -MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i"); -MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA"); #endif MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); diff -Nru a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c --- a/drivers/serial/serial_cs.c Sun Apr 18 13:42:41 2004 +++ b/drivers/serial/serial_cs.c Sun Apr 18 13:42:41 2004 @@ -32,6 +32,7 @@ ======================================================================*/ #include +#include #include #include #include @@ -71,17 +72,18 @@ /* Bit map of interrupts to choose from */ static u_int irq_mask = 0xdeb8; -static int irq_list[4] = { -1 }; +static int irq_list[4]; +static unsigned int irq_list_count; /* Enable the speaker? */ static int do_sound = 1; /* Skip strict UART tests? */ static int buggy_uart; -MODULE_PARM(irq_mask, "i"); -MODULE_PARM(irq_list, "1-4i"); -MODULE_PARM(do_sound, "i"); -MODULE_PARM(buggy_uart, "i"); +module_param(irq_mask, uint, 0444); +module_param_array(irq_list, int, irq_list_count, 0444); +module_param(do_sound, int, 0444); +module_param(buggy_uart, int, 0444); /*====================================================================*/ @@ -221,10 +223,10 @@ link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; - if (irq_list[0] == -1) + if (irq_list_count == 0) link->irq.IRQInfo2 = irq_mask; else - for (i = 0; i < 4; i++) + for (i = 0; i < irq_list_count; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->conf.Attributes = CONF_ENABLE_IRQ; if (do_sound) { diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c Sun Apr 18 13:42:41 2004 +++ b/drivers/usb/gadget/ether.c Sun Apr 18 13:42:41 2004 @@ -2374,9 +2374,7 @@ /* one random address for the gadget device ... both of these could * reasonably come from an id prom or a module parameter. */ - get_random_bytes (net->dev_addr, ETH_ALEN); - net->dev_addr [0] &= 0xfe; // clear multicast bit - net->dev_addr [0] |= 0x02; // set local assignment bit (IEEE802) + random_ether_addr(net->dev_addr); #ifdef DEV_CONFIG_CDC /* ... another address for the host, on the other end of the @@ -2385,9 +2383,7 @@ if (cdc) { u8 node_id [ETH_ALEN]; - get_random_bytes (node_id, sizeof node_id); - node_id [0] &= 0xfe; // clear multicast bit - node_id [0] |= 0x02; // set local assignment bit (IEEE802) + random_ether_addr(node_id); snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", node_id [0], node_id [1], node_id [2], node_id [3], node_id [4], node_id [5]); diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c --- a/drivers/usb/media/vicam.c Sun Apr 18 13:42:40 2004 +++ b/drivers/usb/media/vicam.c Sun Apr 18 13:42:40 2004 @@ -612,15 +612,20 @@ case VIDIOCSPICT: { - struct video_picture *vp = (struct video_picture *) arg; - - DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp->depth, - vp->palette); + struct video_picture vp; + + if (copy_from_user(&vp, arg, sizeof(vp))) { + retval = -EFAULT; + break; + } + + DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth, + vp.palette); - cam->gain = vp->brightness >> 8; + cam->gain = vp.brightness >> 8; - if (vp->depth != 24 - || vp->palette != VIDEO_PALETTE_RGB24) + if (vp.depth != 24 + || vp.palette != VIDEO_PALETTE_RGB24) retval = -EINVAL; break; @@ -660,7 +665,7 @@ break; } - DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height); + DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height); if ( vw.width != 320 || vw.height != 240 ) retval = -EFAULT; diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c --- a/drivers/usb/net/usbnet.c Sun Apr 18 13:42:41 2004 +++ b/drivers/usb/net/usbnet.c Sun Apr 18 13:42:41 2004 @@ -3413,9 +3413,7 @@ < sizeof (struct cdc_state))); #endif - get_random_bytes (node_id, sizeof node_id); - node_id [0] &= 0xfe; // clear multicast bit - node_id [0] |= 0x02; // set local assignment bit (IEEE802) + random_ether_addr(node_id); return usb_register(&usbnet_driver); } diff -Nru a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c --- a/drivers/video/aty/aty128fb.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/aty/aty128fb.c Sun Apr 18 13:42:41 2004 @@ -1998,10 +1998,12 @@ static void __devexit aty128_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - struct aty128fb_par *par = info->par; + struct aty128fb_par *par; if (!info) return; + + par = info->par; unregister_framebuffer(info); #ifdef CONFIG_MTRR diff -Nru a/drivers/video/bw2.c b/drivers/video/bw2.c --- a/drivers/video/bw2.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/bw2.c Sun Apr 18 13:42:41 2004 @@ -162,8 +162,10 @@ } static struct sbus_mmap_map bw2_mmap_map[] = { - { 0, 0, SBUS_MMAP_FBSIZE(1) }, - { 0, 0, 0 } + { + .size = SBUS_MMAP_FBSIZE(1) + }, + { .size = 0 } }; static int bw2_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/drivers/video/cg14.c b/drivers/video/cg14.c --- a/drivers/video/cg14.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/cg14.c Sun Apr 18 13:42:41 2004 @@ -367,23 +367,82 @@ } static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = { - { CG14_REGS, 0x80000000, 0x1000 }, - { CG14_XLUT, 0x80003000, 0x1000 }, - { CG14_CLUT1, 0x80004000, 0x1000 }, - { CG14_CLUT2, 0x80005000, 0x1000 }, - { CG14_CLUT3, 0x80006000, 0x1000 }, - { CG3_MMAP_OFFSET - - 0x7000, 0x80000000, 0x7000 }, - { CG3_MMAP_OFFSET, 0x00000000, SBUS_MMAP_FBSIZE(1) }, - { MDI_CURSOR_MAP, 0x80001000, 0x1000 }, - { MDI_CHUNKY_BGR_MAP, 0x01000000, 0x400000 }, - { MDI_PLANAR_X16_MAP, 0x02000000, 0x200000 }, - { MDI_PLANAR_C16_MAP, 0x02800000, 0x200000 }, - { MDI_PLANAR_X32_MAP, 0x03000000, 0x100000 }, - { MDI_PLANAR_B32_MAP, 0x03400000, 0x100000 }, - { MDI_PLANAR_G32_MAP, 0x03800000, 0x100000 }, - { MDI_PLANAR_R32_MAP, 0x03c00000, 0x100000 }, - { 0, 0, 0 } + { + .voff = CG14_REGS, + .poff = 0x80000000, + .size = 0x1000 + }, + { + .voff = CG14_XLUT, + .poff = 0x80003000, + .size = 0x1000 + }, + { + .voff = CG14_CLUT1, + .poff = 0x80004000, + .size = 0x1000 + }, + { + .voff = CG14_CLUT2, + .poff = 0x80005000, + .size = 0x1000 + }, + { + .voff = CG14_CLUT3, + .poff = 0x80006000, + .size = 0x1000 + }, + { + .voff = CG3_MMAP_OFFSET - 0x7000, + .poff = 0x80000000, + .size = 0x7000 + }, + { + .voff = CG3_MMAP_OFFSET, + .poff = 0x00000000, + .size = SBUS_MMAP_FBSIZE(1) + }, + { + .voff = MDI_CURSOR_MAP, + .poff = 0x80001000, + .size = 0x1000 + }, + { + .voff = MDI_CHUNKY_BGR_MAP, + .poff = 0x01000000, + .size = 0x400000 + }, + { + .voff = MDI_PLANAR_X16_MAP, + .poff = 0x02000000, + .size = 0x200000 + }, + { + .voff = MDI_PLANAR_C16_MAP, + .poff = 0x02800000, + .size = 0x200000 + }, + { + .voff = MDI_PLANAR_X32_MAP, + .poff = 0x03000000, + .size = 0x100000 + }, + { + .voff = MDI_PLANAR_B32_MAP, + .poff = 0x03400000, + .size = 0x100000 + }, + { + .voff = MDI_PLANAR_G32_MAP, + .poff = 0x03800000, + .size = 0x100000 + }, + { + .voff = MDI_PLANAR_R32_MAP, + .poff = 0x03c00000, + .size = 0x100000 + }, + { .size = 0 } }; struct all_info { diff -Nru a/drivers/video/cg3.c b/drivers/video/cg3.c --- a/drivers/video/cg3.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/cg3.c Sun Apr 18 13:42:41 2004 @@ -221,8 +221,12 @@ } static struct sbus_mmap_map cg3_mmap_map[] = { - { CG3_MMAP_OFFSET, CG3_RAM_OFFSET, SBUS_MMAP_FBSIZE(1) }, - { 0, 0, 0 } + { + .poff = CG3_MMAP_OFFSET, + .voff = CG3_RAM_OFFSET, + .size = SBUS_MMAP_FBSIZE(1) + }, + { .size = 0 } }; static int cg3_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/drivers/video/cg6.c b/drivers/video/cg6.c --- a/drivers/video/cg6.c Sun Apr 18 13:42:40 2004 +++ b/drivers/video/cg6.c Sun Apr 18 13:42:40 2004 @@ -480,15 +480,47 @@ } static struct sbus_mmap_map cg6_mmap_map[] = { - { CG6_FBC, CG6_FBC_OFFSET, PAGE_SIZE }, - { CG6_TEC, CG6_TEC_OFFSET, PAGE_SIZE }, - { CG6_BTREGS, CG6_BROOKTREE_OFFSET, PAGE_SIZE }, - { CG6_FHC, CG6_FHC_OFFSET, PAGE_SIZE }, - { CG6_THC, CG6_THC_OFFSET, PAGE_SIZE }, - { CG6_ROM, CG6_ROM_OFFSET, 0x10000 }, - { CG6_RAM, CG6_RAM_OFFSET, SBUS_MMAP_FBSIZE(1) }, - { CG6_DHC, CG6_DHC_OFFSET, 0x40000 }, - { 0, 0, 0 } + { + .voff = CG6_FBC, + .poff = CG6_FBC_OFFSET, + .size = PAGE_SIZE + }, + { + .voff = CG6_TEC, + .poff = CG6_TEC_OFFSET, + .size = PAGE_SIZE + }, + { + .voff = CG6_BTREGS, + .poff = CG6_BROOKTREE_OFFSET, + .size = PAGE_SIZE + }, + { + .voff = CG6_FHC, + .poff = CG6_FHC_OFFSET, + .size = PAGE_SIZE + }, + { + .voff = CG6_THC, + .poff = CG6_THC_OFFSET, + .size = PAGE_SIZE + }, + { + .voff = CG6_ROM, + .poff = CG6_ROM_OFFSET, + .size = 0x10000 + }, + { + .voff = CG6_RAM, + .poff = CG6_RAM_OFFSET, + .size = SBUS_MMAP_FBSIZE(1) + }, + { + .voff = CG6_DHC, + .poff = CG6_DHC_OFFSET, + .size = 0x40000 + }, + { .size = 0 } }; static int cg6_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c --- a/drivers/video/fbmem.c Sun Apr 18 13:42:40 2004 +++ b/drivers/video/fbmem.c Sun Apr 18 13:42:40 2004 @@ -32,6 +32,9 @@ #include #endif #include +#include +#include +#include #if defined(__mc68000__) || defined(CONFIG_APUS) #include @@ -1245,6 +1248,8 @@ #endif }; +static struct class_simple *fb_class; + /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1259,6 +1264,7 @@ register_framebuffer(struct fb_info *fb_info) { int i; + struct class_device *c; if (num_registered_fb == FB_MAX) return -ENXIO; @@ -1267,6 +1273,12 @@ if (!registered_fb[i]) break; fb_info->node = i; + + c = class_simple_device_add(fb_class, MKDEV(FB_MAJOR, i), NULL, "fb%d", i); + if (IS_ERR(c)) { + /* Not fatal */ + printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c)); + } if (fb_info->pixmap.addr == NULL) { fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); @@ -1332,6 +1344,7 @@ kfree(fb_info->sprite.addr); registered_fb[i]=NULL; num_registered_fb--; + class_simple_device_remove(MKDEV(FB_MAJOR, i)); return 0; } @@ -1392,6 +1405,12 @@ devfs_mk_dir("fb"); if (register_chrdev(FB_MAJOR,"fb",&fb_fops)) printk("unable to get major %d for fb devs\n", FB_MAJOR); + + fb_class = class_simple_create(THIS_MODULE, "graphics"); + if (IS_ERR(fb_class)) { + printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class)); + fb_class = NULL; + } #ifdef CONFIG_FB_OF if (ofonly) { diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c --- a/drivers/video/ffb.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/ffb.c Sun Apr 18 13:42:41 2004 @@ -769,34 +769,142 @@ } static struct sbus_mmap_map ffb_mmap_map[] = { - { FFB_SFB8R_VOFF, FFB_SFB8R_POFF, 0x0400000 }, - { FFB_SFB8G_VOFF, FFB_SFB8G_POFF, 0x0400000 }, - { FFB_SFB8B_VOFF, FFB_SFB8B_POFF, 0x0400000 }, - { FFB_SFB8X_VOFF, FFB_SFB8X_POFF, 0x0400000 }, - { FFB_SFB32_VOFF, FFB_SFB32_POFF, 0x1000000 }, - { FFB_SFB64_VOFF, FFB_SFB64_POFF, 0x2000000 }, - { FFB_FBC_REGS_VOFF, FFB_FBC_REGS_POFF, 0x0002000 }, - { FFB_BM_FBC_REGS_VOFF, FFB_BM_FBC_REGS_POFF, 0x0002000 }, - { FFB_DFB8R_VOFF, FFB_DFB8R_POFF, 0x0400000 }, - { FFB_DFB8G_VOFF, FFB_DFB8G_POFF, 0x0400000 }, - { FFB_DFB8B_VOFF, FFB_DFB8B_POFF, 0x0400000 }, - { FFB_DFB8X_VOFF, FFB_DFB8X_POFF, 0x0400000 }, - { FFB_DFB24_VOFF, FFB_DFB24_POFF, 0x1000000 }, - { FFB_DFB32_VOFF, FFB_DFB32_POFF, 0x1000000 }, - { FFB_FBC_KREGS_VOFF, FFB_FBC_KREGS_POFF, 0x0002000 }, - { FFB_DAC_VOFF, FFB_DAC_POFF, 0x0002000 }, - { FFB_PROM_VOFF, FFB_PROM_POFF, 0x0010000 }, - { FFB_EXP_VOFF, FFB_EXP_POFF, 0x0002000 }, - { FFB_DFB422A_VOFF, FFB_DFB422A_POFF, 0x0800000 }, - { FFB_DFB422AD_VOFF, FFB_DFB422AD_POFF, 0x0800000 }, - { FFB_DFB24B_VOFF, FFB_DFB24B_POFF, 0x1000000 }, - { FFB_DFB422B_VOFF, FFB_DFB422B_POFF, 0x0800000 }, - { FFB_DFB422BD_VOFF, FFB_DFB422BD_POFF, 0x0800000 }, - { FFB_SFB16Z_VOFF, FFB_SFB16Z_POFF, 0x0800000 }, - { FFB_SFB8Z_VOFF, FFB_SFB8Z_POFF, 0x0800000 }, - { FFB_SFB422_VOFF, FFB_SFB422_POFF, 0x0800000 }, - { FFB_SFB422D_VOFF, FFB_SFB422D_POFF, 0x0800000 }, - { 0, 0, 0 } + { + .voff = FFB_SFB8R_VOFF, + .poff = FFB_SFB8R_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_SFB8G_VOFF, + .poff = FFB_SFB8G_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_SFB8B_VOFF, + .poff = FFB_SFB8B_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_SFB8X_VOFF, + .poff = FFB_SFB8X_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_SFB32_VOFF, + .poff = FFB_SFB32_POFF, + .size = 0x1000000 + }, + { + .voff = FFB_SFB64_VOFF, + .poff = FFB_SFB64_POFF, + .size = 0x2000000 + }, + { + .voff = FFB_FBC_REGS_VOFF, + .poff = FFB_FBC_REGS_POFF, + .size = 0x0002000 + }, + { + .voff = FFB_BM_FBC_REGS_VOFF, + .poff = FFB_BM_FBC_REGS_POFF, + .size = 0x0002000 + }, + { + .voff = FFB_DFB8R_VOFF, + .poff = FFB_DFB8R_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_DFB8G_VOFF, + .poff = FFB_DFB8G_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_DFB8B_VOFF, + .poff = FFB_DFB8B_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_DFB8X_VOFF, + .poff = FFB_DFB8X_POFF, + .size = 0x0400000 + }, + { + .voff = FFB_DFB24_VOFF, + .poff = FFB_DFB24_POFF, + .size = 0x1000000 + }, + { + .voff = FFB_DFB32_VOFF, + .poff = FFB_DFB32_POFF, + .size = 0x1000000 + }, + { + .voff = FFB_FBC_KREGS_VOFF, + .poff = FFB_FBC_KREGS_POFF, + .size = 0x0002000 + }, + { + .voff = FFB_DAC_VOFF, + .poff = FFB_DAC_POFF, + .size = 0x0002000 + }, + { + .voff = FFB_PROM_VOFF, + .poff = FFB_PROM_POFF, + .size = 0x0010000 + }, + { + .voff = FFB_EXP_VOFF, + .poff = FFB_EXP_POFF, + .size = 0x0002000 + }, + { + .voff = FFB_DFB422A_VOFF, + .poff = FFB_DFB422A_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_DFB422AD_VOFF, + .poff = FFB_DFB422AD_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_DFB24B_VOFF, + .poff = FFB_DFB24B_POFF, + .size = 0x1000000 + }, + { + .voff = FFB_DFB422B_VOFF, + .poff = FFB_DFB422B_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_DFB422BD_VOFF, + .poff = FFB_DFB422BD_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_SFB16Z_VOFF, + .poff = FFB_SFB16Z_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_SFB8Z_VOFF, + .poff = FFB_SFB8Z_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_SFB422_VOFF, + .poff = FFB_SFB422_POFF, + .size = 0x0800000 + }, + { + .voff = FFB_SFB422D_VOFF, + .poff = FFB_SFB422D_POFF, + .size = 0x0800000 + }, + { .size = 0 } }; static int ffb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/drivers/video/leo.c b/drivers/video/leo.c --- a/drivers/video/leo.c Sun Apr 18 13:42:41 2004 +++ b/drivers/video/leo.c Sun Apr 18 13:42:41 2004 @@ -294,20 +294,72 @@ } static struct sbus_mmap_map leo_mmap_map[] = { - { LEO_SS0_MAP, LEO_OFF_SS0, 0x800000 }, - { LEO_LC_SS0_USR_MAP, LEO_OFF_LC_SS0_USR, 0x1000 }, - { LEO_LD_SS0_MAP, LEO_OFF_LD_SS0, 0x1000 }, - { LEO_LX_CURSOR_MAP, LEO_OFF_LX_CURSOR, 0x1000 }, - { LEO_SS1_MAP, LEO_OFF_SS1, 0x800000 }, - { LEO_LC_SS1_USR_MAP, LEO_OFF_LC_SS1_USR, 0x1000 }, - { LEO_LD_SS1_MAP, LEO_OFF_LD_SS1, 0x1000 }, - { LEO_UNK_MAP, LEO_OFF_UNK, 0x1000 }, - { LEO_LX_KRN_MAP, LEO_OFF_LX_KRN, 0x1000 }, - { LEO_LC_SS0_KRN_MAP, LEO_OFF_LC_SS0_KRN, 0x1000 }, - { LEO_LC_SS1_KRN_MAP, LEO_OFF_LC_SS1_KRN, 0x1000 }, - { LEO_LD_GBL_MAP, LEO_OFF_LD_GBL, 0x1000 }, - { LEO_UNK2_MAP, LEO_OFF_UNK2, 0x100000 }, - { 0, 0, 0 } + { + .voff = LEO_SS0_MAP, + .poff = LEO_OFF_SS0, + .size = 0x800000 + }, + { + .voff = LEO_LC_SS0_USR_MAP, + .poff = LEO_OFF_LC_SS0_USR, + .size = 0x1000 + }, + { + .voff = LEO_LD_SS0_MAP, + .poff = LEO_OFF_LD_SS0, + .size = 0x1000 + }, + { + .voff = LEO_LX_CURSOR_MAP, + .poff = LEO_OFF_LX_CURSOR, + .size = 0x1000 + }, + { + .voff = LEO_SS1_MAP, + .poff = LEO_OFF_SS1, + .size = 0x800000 + }, + { + .voff = LEO_LC_SS1_USR_MAP, + .poff = LEO_OFF_LC_SS1_USR, + .size = 0x1000 + }, + { + .voff = LEO_LD_SS1_MAP, + .poff = LEO_OFF_LD_SS1, + .size = 0x1000 + }, + { + .voff = LEO_UNK_MAP, + .poff = LEO_OFF_UNK, + .size = 0x1000 + }, + { + .voff = LEO_LX_KRN_MAP, + .poff = LEO_OFF_LX_KRN, + .size = 0x1000 + }, + { + .voff = LEO_LC_SS0_KRN_MAP, + .poff = LEO_OFF_LC_SS0_KRN, + .size = 0x1000 + }, + { + .voff = LEO_LC_SS1_KRN_MAP, + .poff = LEO_OFF_LC_SS1_KRN, + .size = 0x1000 + }, + { + .voff = LEO_LD_GBL_MAP, + .poff = LEO_OFF_LD_GBL, + .size = 0x1000 + }, + { + .voff = LEO_UNK2_MAP, + .poff = LEO_OFF_UNK2, + .size = 0x100000 + }, + { .size = 0 } }; static int leo_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/drivers/video/tcx.c b/drivers/video/tcx.c --- a/drivers/video/tcx.c Sun Apr 18 13:42:40 2004 +++ b/drivers/video/tcx.c Sun Apr 18 13:42:40 2004 @@ -238,20 +238,59 @@ } static struct sbus_mmap_map __tcx_mmap_map[TCX_MMAP_ENTRIES] = { - { TCX_RAM8BIT, 0, SBUS_MMAP_FBSIZE(1) }, - { TCX_RAM24BIT, 0, SBUS_MMAP_FBSIZE(4) }, - { TCX_UNK3, 0, SBUS_MMAP_FBSIZE(8) }, - { TCX_UNK4, 0, SBUS_MMAP_FBSIZE(8) }, - { TCX_CONTROLPLANE, 0, SBUS_MMAP_FBSIZE(4) }, - { TCX_UNK6, 0, SBUS_MMAP_FBSIZE(8) }, - { TCX_UNK7, 0, SBUS_MMAP_FBSIZE(8) }, - { TCX_TEC, 0, PAGE_SIZE }, - { TCX_BTREGS, 0, PAGE_SIZE }, - { TCX_THC, 0, PAGE_SIZE }, - { TCX_DHC, 0, PAGE_SIZE }, - { TCX_ALT, 0, PAGE_SIZE }, - { TCX_UNK2, 0, 0x20000 }, - { 0, 0, 0 } + { + .voff = TCX_RAM8BIT, + .size = SBUS_MMAP_FBSIZE(1) + }, + { + .voff = TCX_RAM24BIT, + .size = SBUS_MMAP_FBSIZE(4) + }, + { + .voff = TCX_UNK3, + .size = SBUS_MMAP_FBSIZE(8) + }, + { + .voff = TCX_UNK4, + .size = SBUS_MMAP_FBSIZE(8) + }, + { + .voff = TCX_CONTROLPLANE, + .size = SBUS_MMAP_FBSIZE(4) + }, + { + .voff = TCX_UNK6, + .size = SBUS_MMAP_FBSIZE(8) + }, + { + .voff = TCX_UNK7, + .size = SBUS_MMAP_FBSIZE(8) + }, + { + .voff = TCX_TEC, + .size = PAGE_SIZE + }, + { + .voff = TCX_BTREGS, + .size = PAGE_SIZE + }, + { + .voff = TCX_THC, + .size = PAGE_SIZE + }, + { + .voff = TCX_DHC, + .size = PAGE_SIZE + }, + { + .voff = TCX_ALT, + .size = PAGE_SIZE + }, + { + .voff = TCX_UNK2, + .size = 0x20000 + }, + { .size = 0 } }; static int tcx_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma) diff -Nru a/fs/Kconfig b/fs/Kconfig --- a/fs/Kconfig Sun Apr 18 13:42:41 2004 +++ b/fs/Kconfig Sun Apr 18 13:42:41 2004 @@ -406,12 +406,15 @@ help If you say Y here, you will be able to set per user limits for disk usage (also called disk quotas). Currently, it works for the - ext2, ext3, and reiserfs file system. You need additional software - in order to use quota support (you can download sources from + ext2, ext3, and reiserfs file system. ext3 also supports journalled + quotas for which you don't need to run quotacheck(8) after an unclean + shutdown. You need additional software in order to use quota support + (you can download sources from ). For further details, read the Quota mini-HOWTO, available from - . Probably the quota - support is only useful for multi user systems. If unsure, say N. + , or the documentation provided + with the quota tools. Probably the quota support is only useful for + multi user systems. If unsure, say N. config QFMT_V1 tristate "Old quota format support" diff -Nru a/fs/adfs/super.c b/fs/adfs/super.c --- a/fs/adfs/super.c Sun Apr 18 13:42:40 2004 +++ b/fs/adfs/super.c Sun Apr 18 13:42:40 2004 @@ -192,6 +192,7 @@ static int adfs_remount(struct super_block *sb, int *flags, char *data) { + *flags |= MS_NODIRATIME; return parse_options(sb, data); } diff -Nru a/fs/affs/super.c b/fs/affs/super.c --- a/fs/affs/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/affs/super.c Sun Apr 18 13:42:41 2004 @@ -502,6 +502,8 @@ pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data); + *flags |= MS_NODIRATIME; + if (!parse_options(data,&uid,&gid,&mode,&reserved,&root_block, &blocksize,&sbi->s_prefix,sbi->s_volume,&mount_flags)) return -EINVAL; diff -Nru a/fs/buffer.c b/fs/buffer.c --- a/fs/buffer.c Sun Apr 18 13:42:41 2004 +++ b/fs/buffer.c Sun Apr 18 13:42:41 2004 @@ -51,25 +51,6 @@ wait_queue_head_t wqh; } ____cacheline_aligned_in_smp bh_wait_queue_heads[1< 10) - return; - enough++; - printk("buffer layer error at %s:%d\n", file, line); -#ifndef CONFIG_KALLSYMS - printk("Pass this trace through ksymoops for reporting\n"); -#endif - dump_stack(); -} -EXPORT_SYMBOL(__buffer_error); - inline void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private) { @@ -99,17 +80,6 @@ void fastcall unlock_buffer(struct buffer_head *bh) { - /* - * unlock_buffer against a zero-count bh is a bug, if the page - * is not locked. Because then nothing protects the buffer's - * waitqueue, which is used here. (Well. Other locked buffers - * against the page will pin it. But complain anyway). - */ - if (atomic_read(&bh->b_count) == 0 && - !PageLocked(bh->b_page) && - !PageWriteback(bh->b_page)) - buffer_error(); - clear_buffer_locked(bh); smp_mb__after_clear_bit(); wake_up_buffer(bh); @@ -125,10 +95,6 @@ wait_queue_head_t *wqh = bh_waitq_head(bh); DEFINE_WAIT(wait); - if (atomic_read(&bh->b_count) == 0 && - (!bh->b_page || !PageLocked(bh->b_page))) - buffer_error(); - do { prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); if (buffer_locked(bh)) { @@ -146,8 +112,6 @@ static void __set_page_buffers(struct page *page, struct buffer_head *head) { - if (page_has_buffers(page)) - buffer_error(); page_cache_get(page); SetPagePrivate(page); page->private = (unsigned long)head; @@ -433,10 +397,12 @@ } bh = bh->b_this_page; } while (bh != head); - buffer_error(); - printk("block=%llu, b_blocknr=%llu\n", + + printk("__find_get_block_slow() failed. " + "block=%llu, b_blocknr=%llu\n", (unsigned long long)block, (unsigned long long)bh->b_blocknr); printk("b_state=0x%08lx, b_size=%u\n", bh->b_state, bh->b_size); + printk("device blocksize: %d\n", 1 << bd_inode->i_blkbits); out_unlock: spin_unlock(&bd_mapping->private_lock); page_cache_release(page); @@ -847,10 +813,7 @@ struct buffer_head *bh = head; do { - if (buffer_uptodate(bh)) - set_buffer_dirty(bh); - else - buffer_error(); + set_buffer_dirty(bh); bh = bh->b_this_page; } while (bh != head); } @@ -1151,7 +1114,7 @@ return page; failed: - buffer_error(); + BUG(); unlock_page(page); page_cache_release(page); return NULL; @@ -1247,8 +1210,6 @@ */ void fastcall mark_buffer_dirty(struct buffer_head *bh) { - if (!buffer_uptodate(bh)) - buffer_error(); if (!buffer_dirty(bh) && !test_set_buffer_dirty(bh)) __set_page_dirty_nobuffers(bh->b_page); } @@ -1267,7 +1228,7 @@ return; } printk(KERN_ERR "VFS: brelse: Trying to free free buffer\n"); - buffer_error(); /* For the stack backtrace */ + WARN_ON(1); } /* @@ -1294,8 +1255,6 @@ unlock_buffer(bh); return bh; } else { - if (buffer_dirty(bh)) - buffer_error(); get_bh(bh); bh->b_end_io = end_buffer_read_sync; submit_bh(READ, bh); @@ -1686,10 +1645,6 @@ old_bh = __find_get_block_slow(bdev, block, 0); if (old_bh) { -#if 0 /* This happens. Later. */ - if (buffer_dirty(old_bh)) - buffer_error(); -#endif clear_buffer_dirty(old_bh); wait_on_buffer(old_bh); clear_buffer_req(old_bh); @@ -1737,8 +1692,6 @@ last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; if (!page_has_buffers(page)) { - if (!PageUptodate(page)) - buffer_error(); create_empty_buffers(page, 1 << inode->i_blkbits, (1 << BH_Dirty)|(1 << BH_Uptodate)); } @@ -1767,9 +1720,6 @@ * mapped buffers outside i_size will occur, because * this page can be outside i_size when there is a * truncate in progress. - * - * if (buffer_mapped(bh)) - * buffer_error(); */ /* * The buffer was zeroed by block_write_full_page() @@ -1777,8 +1727,6 @@ clear_buffer_dirty(bh); set_buffer_uptodate(bh); } else if (!buffer_mapped(bh) && buffer_dirty(bh)) { - if (buffer_new(bh)) - buffer_error(); err = get_block(inode, block, bh, 1); if (err) goto recover; @@ -1811,8 +1759,6 @@ continue; } if (test_clear_buffer_dirty(bh)) { - if (!buffer_uptodate(bh)) - buffer_error(); mark_buffer_async_write(bh); } else { unlock_buffer(bh); @@ -1942,8 +1888,6 @@ unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); if (PageUptodate(page)) { - if (!buffer_mapped(bh)) - buffer_error(); set_buffer_uptodate(bh); continue; } @@ -2001,8 +1945,6 @@ void *kaddr; clear_buffer_new(bh); - if (buffer_uptodate(bh)) - buffer_error(); kaddr = kmap_atomic(page, KM_USER0); memset(kaddr+block_start, 0, bh->b_size); kunmap_atomic(kaddr, KM_USER0); @@ -2068,8 +2010,6 @@ if (!PageLocked(page)) PAGE_BUG(page); - if (PageUptodate(page)) - buffer_error(); blocksize = 1 << inode->i_blkbits; if (!page_has_buffers(page)) create_empty_buffers(page, blocksize, 0); @@ -2684,7 +2624,7 @@ return 0; } -int submit_bh(int rw, struct buffer_head * bh) +void submit_bh(int rw, struct buffer_head * bh) { struct bio *bio; @@ -2692,13 +2632,6 @@ BUG_ON(!buffer_mapped(bh)); BUG_ON(!bh->b_end_io); - if ((rw == READ || rw == READA) && buffer_uptodate(bh)) - buffer_error(); - if (rw == WRITE && !buffer_uptodate(bh)) - buffer_error(); - if (rw == READ && buffer_dirty(bh)) - buffer_error(); - /* Only clear out a write error when rewriting */ if (test_set_buffer_req(bh) && rw == WRITE) clear_buffer_write_io_error(bh); @@ -2722,7 +2655,7 @@ bio->bi_end_io = end_bio_bh_io_sync; bio->bi_private = bh; - return submit_bio(rw, bio); + submit_bio(rw, bio); } /** @@ -2798,21 +2731,6 @@ } /* - * Sanity checks for try_to_free_buffers. - */ -static void check_ttfb_buffer(struct page *page, struct buffer_head *bh) -{ - if (!buffer_uptodate(bh) && !buffer_req(bh)) { - if (PageUptodate(page) && page->mapping - && buffer_mapped(bh) /* discard_buffer */ - && S_ISBLK(page->mapping->host->i_mode)) - { - buffer_error(); - } - } -} - -/* * try_to_free_buffers() checks if all the buffers on this particular page * are unused, and releases them if so. * @@ -2847,7 +2765,6 @@ bh = head; do { - check_ttfb_buffer(page, bh); if (buffer_write_io_error(bh)) set_bit(AS_EIO, &page->mapping->flags); if (buffer_busy(bh)) @@ -2856,9 +2773,6 @@ was_uptodate = 0; bh = bh->b_this_page; } while (bh != head); - - if (!was_uptodate && PageUptodate(page) && !PageError(page)) - buffer_error(); do { struct buffer_head *next = bh->b_this_page; diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c Sun Apr 18 13:42:41 2004 +++ b/fs/cifs/cifsfs.c Sun Apr 18 13:42:41 2004 @@ -357,6 +357,12 @@ }; #endif +static int cifs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + struct super_operations cifs_super_ops = { .read_inode = cifs_read_inode, .put_super = cifs_put_super, @@ -369,6 +375,7 @@ us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, /* .umount_begin = cifs_umount_begin, *//* consider adding in the future */ + .remount_fs = cifs_remount, }; static struct super_block * diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c --- a/fs/coda/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/coda/inode.c Sun Apr 18 13:42:41 2004 @@ -82,6 +82,12 @@ printk(KERN_INFO "coda_inode_cache: not all structures were freed\n"); } +static int coda_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + /* exported operations */ struct super_operations coda_super_operations = { @@ -90,6 +96,7 @@ .clear_inode = coda_clear_inode, .put_super = coda_put_super, .statfs = coda_statfs, + .remount_fs = coda_remount, }; static int get_device_index(struct coda_mount_data *data) diff -Nru a/fs/coda/psdev.c b/fs/coda/psdev.c --- a/fs/coda/psdev.c Sun Apr 18 13:42:41 2004 +++ b/fs/coda/psdev.c Sun Apr 18 13:42:41 2004 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ struct venus_comm coda_comms[MAX_CODADEVS]; +static struct class_simple *coda_psdev_class; /* * Device operations @@ -358,20 +360,38 @@ static int init_coda_psdev(void) { - int i; + int i, err = 0; if (register_chrdev(CODA_PSDEV_MAJOR,"coda_psdev", &coda_psdev_fops)) { printk(KERN_ERR "coda_psdev: unable to get major %d\n", CODA_PSDEV_MAJOR); return -EIO; } + coda_psdev_class = class_simple_create(THIS_MODULE, "coda_psdev"); + if (IS_ERR(coda_psdev_class)) { + err = PTR_ERR(coda_psdev_class); + goto out_chrdev; + } devfs_mk_dir ("coda"); for (i = 0; i < MAX_CODADEVS; i++) { - devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i), + class_simple_device_add(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i), + NULL, "cfs%d", i); + err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i), S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i); + if (err) + goto out_class; } coda_sysctl_init(); - return 0; + goto out; + +out_class: + for (i = 0; i < MAX_CODADEVS; i++) + class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); + class_simple_destroy(coda_psdev_class); +out_chrdev: + unregister_chrdev(CODA_PSDEV_MAJOR, "coda_psdev"); +out: + return err; } @@ -408,8 +428,11 @@ } return 0; out: - for (i = 0; i < MAX_CODADEVS; i++) + for (i = 0; i < MAX_CODADEVS; i++) { + class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); devfs_remove("coda/%d", i); + } + class_simple_destroy(coda_psdev_class); devfs_remove("coda"); unregister_chrdev(CODA_PSDEV_MAJOR,"coda_psdev"); coda_sysctl_clean(); @@ -427,8 +450,11 @@ if ( err != 0 ) { printk("coda: failed to unregister filesystem\n"); } - for (i = 0; i < MAX_CODADEVS; i++) + for (i = 0; i < MAX_CODADEVS; i++) { + class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i)); devfs_remove("coda/%d", i); + } + class_simple_destroy(coda_psdev_class); devfs_remove("coda"); unregister_chrdev(CODA_PSDEV_MAJOR, "coda_psdev"); coda_sysctl_clean(); diff -Nru a/fs/cramfs/inode.c b/fs/cramfs/inode.c --- a/fs/cramfs/inode.c Sun Apr 18 13:42:40 2004 +++ b/fs/cramfs/inode.c Sun Apr 18 13:42:40 2004 @@ -193,6 +193,12 @@ sb->s_fs_info = NULL; } +static int cramfs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_RDONLY; + return 0; +} + static int cramfs_fill_super(struct super_block *sb, void *data, int silent) { int i; @@ -483,6 +489,7 @@ static struct super_operations cramfs_ops = { .put_super = cramfs_put_super, + .remount_fs = cramfs_remount, .statfs = cramfs_statfs, }; diff -Nru a/fs/dquot.c b/fs/dquot.c --- a/fs/dquot.c Sun Apr 18 13:42:41 2004 +++ b/fs/dquot.c Sun Apr 18 13:42:41 2004 @@ -1,16 +1,13 @@ /* - * Implementation of the diskquota system for the LINUX operating - * system. QUOTA is implemented using the BSD system call interface as - * the means of communication with the user level. Currently only the - * ext2 filesystem has support for disk quotas. Other filesystems may - * be added in the future. This file contains the generic routines - * called by the different filesystems on allocation of an inode or - * block. These routines take care of the administration needed to - * have a consistent diskquota tracking system. The ideas of both - * user and group quotas are based on the Melbourne quota system as - * used on BSD derived systems. The internal implementation is - * based on one of the several variants of the LINUX inode-subsystem - * with added complexity of the diskquota system. + * Implementation of the diskquota system for the LINUX operating system. QUOTA + * is implemented using the BSD system call interface as the means of + * communication with the user level. This file contains the generic routines + * called by the different filesystems on allocation of an inode or block. + * These routines take care of the administration needed to have a consistent + * diskquota tracking system. The ideas of both user and group quotas are based + * on the Melbourne quota system as used on BSD derived systems. The internal + * implementation is based on one of the several variants of the LINUX + * inode-subsystem with added complexity of the diskquota system. * * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $ * @@ -52,6 +49,9 @@ * New SMP locking. * Jan Kara, , 10/2002 * + * Added journalled quota support + * Jan Kara, , 2003,2004 + * * (C) Copyright 1994 - 1997 Marco van Wieringen */ @@ -104,13 +104,17 @@ * * Each dquot has its dq_lock semaphore. Locked dquots might not be referenced * from inodes (dquot_alloc_space() and such don't check the dq_lock). - * Currently dquot is locked only when it is being read to memory on the first - * dqget(). Write operations on dquots don't hold dq_lock as they copy data - * under dq_data_lock spinlock to internal buffers before writing. + * Currently dquot is locked only when it is being read to memory (or space for + * it is being allocated) on the first dqget() and when it is being released on + * the last dqput(). The allocation and release oparations are serialized by + * the dq_lock and by checking the use count in dquot_release(). Write + * operations on dquots don't hold dq_lock as they copy data under dq_data_lock + * spinlock to internal buffers before writing. * * Lock ordering (including journal_lock) is following: * dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > dqio_sem */ + spinlock_t dq_list_lock = SPIN_LOCK_UNLOCKED; spinlock_t dq_data_lock = SPIN_LOCK_UNLOCKED; @@ -256,6 +260,9 @@ dqstats.allocated_dquots--; list_del(&dquot->dq_inuse); } +/* + * End of list functions needing dq_list_lock + */ static void wait_on_dquot(struct dquot *dquot) { @@ -263,34 +270,98 @@ up(&dquot->dq_lock); } -static int read_dqblk(struct dquot *dquot) +#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot)) + +/* No locks needed here as ANY_DQUOT_DIRTY is used just by sync and so the + * worst what can happen is that dquot is not written by concurrent sync... */ +int dquot_mark_dquot_dirty(struct dquot *dquot) +{ + set_bit(DQ_MOD_B, &(dquot)->dq_flags); + set_bit(DQF_ANY_DQUOT_DIRTY_B, &(sb_dqopt((dquot)->dq_sb)-> + info[(dquot)->dq_type].dqi_flags)); + return 0; +} + +void mark_info_dirty(struct super_block *sb, int type) { - int ret; + set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags); +} +EXPORT_SYMBOL(mark_info_dirty); + +/* + * Read dquot from disk and alloc space for it + */ + +int dquot_acquire(struct dquot *dquot) +{ + int ret = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); down(&dquot->dq_lock); down(&dqopt->dqio_sem); - ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); + if (!test_bit(DQ_READ_B, &dquot->dq_flags)) + ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); + if (ret < 0) + goto out_iolock; + set_bit(DQ_READ_B, &dquot->dq_flags); + /* Instantiate dquot if needed */ + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { + ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); + if (ret < 0) + goto out_iolock; + } + set_bit(DQ_ACTIVE_B, &dquot->dq_flags); +out_iolock: up(&dqopt->dqio_sem); up(&dquot->dq_lock); return ret; } -static int commit_dqblk(struct dquot *dquot) +/* + * Write dquot to disk + */ +int dquot_commit(struct dquot *dquot) { - int ret; + int ret = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); down(&dqopt->dqio_sem); - ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); + clear_bit(DQ_MOD_B, &dquot->dq_flags); + /* Inactive dquot can be only if there was error during read/init + * => we have better not writing it */ + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); up(&dqopt->dqio_sem); + if (info_dirty(&dqopt->info[dquot->dq_type])) + dquot->dq_sb->dq_op->write_info(dquot->dq_sb, dquot->dq_type); + return ret; +} + +/* + * Release dquot + */ +int dquot_release(struct dquot *dquot) +{ + int ret = 0; + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + + down(&dquot->dq_lock); + /* Check whether we are not racing with some other dqget() */ + if (atomic_read(&dquot->dq_count) > 1) + goto out_dqlock; + down(&dqopt->dqio_sem); + ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); + clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); + up(&dqopt->dqio_sem); +out_dqlock: + up(&dquot->dq_lock); return ret; } /* Invalidate all dquots on the list. Note that this function is called after - * quota is disabled so no new quota might be created. Because we hold - * dqonoff_sem and pointers were already removed from inodes we actually know - * that no quota for this sb+type should be held. */ + * quota is disabled and pointers from inodes removed so there cannot be new + * quota users. Also because we hold dqonoff_sem there can be no quota users + * for this sb+type at all. */ static void invalidate_dquots(struct super_block *sb, int type) { struct dquot *dquot; @@ -317,7 +388,7 @@ spin_unlock(&dq_list_lock); } -static int vfs_quota_sync(struct super_block *sb, int type) +int vfs_quota_sync(struct super_block *sb, int type) { struct list_head *head; struct dquot *dquot; @@ -328,9 +399,11 @@ restart: /* At this point any dirty dquot will definitely be written so we can clear dirty flag from info */ + spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt)) clear_bit(DQF_ANY_DQUOT_DIRTY_B, &dqopt->info[cnt].dqi_flags); + spin_unlock(&dq_data_lock); spin_lock(&dq_list_lock); list_for_each(head, &inuse_list) { dquot = list_entry(head, struct dquot, dq_inuse); @@ -338,10 +411,13 @@ continue; if (type != -1 && dquot->dq_type != type) continue; - if (!dquot->dq_sb) /* Invalidated? */ - continue; if (!dquot_dirty(dquot)) continue; + /* Dirty and inactive can be only bad dquot... */ + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + continue; + /* Now we have active dquot from which someone is holding reference so we + * can safely just increase use count */ atomic_inc(&dquot->dq_count); dqstats.lookups++; spin_unlock(&dq_list_lock); @@ -352,11 +428,9 @@ spin_unlock(&dq_list_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) && info_dirty(&dqopt->info[cnt])) { - down(&dqopt->dqio_sem); - dqopt->ops[cnt]->write_file_info(sb, cnt); - up(&dqopt->dqio_sem); - } + if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) + && info_dirty(&dqopt->info[cnt])) + sb->dq_op->write_info(sb, cnt); spin_lock(&dq_list_lock); dqstats.syncs++; spin_unlock(&dq_list_lock); @@ -431,11 +505,20 @@ spin_unlock(&dq_list_lock); return; } - if (dquot_dirty(dquot)) { + /* Need to release dquot? */ + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) { spin_unlock(&dq_list_lock); + /* Commit dquot before releasing */ dquot->dq_sb->dq_op->write_dquot(dquot); goto we_slept; } + /* Clear flag in case dquot was inactive (something bad happened) */ + clear_bit(DQ_MOD_B, &dquot->dq_flags); + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + spin_unlock(&dq_list_lock); + dquot_release(dquot); + goto we_slept; + } atomic_dec(&dquot->dq_count); #ifdef __DQUOT_PARANOIA /* sanity check */ @@ -494,7 +577,6 @@ insert_dquot_hash(dquot); dqstats.lookups++; spin_unlock(&dq_list_lock); - read_dqblk(dquot); } else { if (!atomic_read(&dquot->dq_count)) remove_free_dquot(dquot); @@ -502,11 +584,17 @@ dqstats.cache_hits++; dqstats.lookups++; spin_unlock(&dq_list_lock); - wait_on_dquot(dquot); if (empty) kmem_cache_free(dquot_cachep, empty); } - + /* Wait for dq_lock - after this we know that either dquot_release() is already + * finished or it will be canceled due to dq_count > 1 test */ + wait_on_dquot(dquot); + /* Read the dquot and instantiate it (everything done only if needed) */ + if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_acquire(dquot) < 0) { + dqput(dquot); + return NODQUOT; + } #ifdef __DQUOT_PARANOIA if (!dquot->dq_sb) /* Has somebody invalidated entry under us? */ BUG(); @@ -540,12 +628,10 @@ struct file *filp = list_entry(p, struct file, f_list); struct inode *inode = filp->f_dentry->d_inode; if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) { - struct vfsmount *mnt = mntget(filp->f_vfsmnt); struct dentry *dentry = dget(filp->f_dentry); file_list_unlock(); sb->dq_op->initialize(inode, type); dput(dentry); - mntput(mnt); /* As we may have blocked we had better restart... */ goto restart; } @@ -627,13 +713,11 @@ static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number) { dquot->dq_dqb.dqb_curinodes += number; - mark_dquot_dirty(dquot); } static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) { dquot->dq_dqb.dqb_curspace += number; - mark_dquot_dirty(dquot); } static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number) @@ -645,7 +729,6 @@ if (dquot->dq_dqb.dqb_curinodes < dquot->dq_dqb.dqb_isoftlimit) dquot->dq_dqb.dqb_itime = (time_t) 0; clear_bit(DQ_INODES_B, &dquot->dq_flags); - mark_dquot_dirty(dquot); } static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) @@ -657,7 +740,6 @@ if (toqb(dquot->dq_dqb.dqb_curspace) < dquot->dq_dqb.dqb_bsoftlimit) dquot->dq_dqb.dqb_btime = (time_t) 0; clear_bit(DQ_BLKS_B, &dquot->dq_flags); - mark_dquot_dirty(dquot); } static inline int need_print_warning(struct dquot *dquot) @@ -810,25 +892,22 @@ } /* - * Externally referenced functions through dquot_operations in inode. - * - * Note: this is a blocking operation. + * Initialize quota pointers in inode + * Transaction must be started at entry */ -void dquot_initialize(struct inode *inode, int type) +int dquot_initialize(struct inode *inode, int type) { unsigned int id = 0; - int cnt; + int cnt, ret = 0; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) - return; + return 0; down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ - if (IS_NOQUOTA(inode)) { - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - return; - } - /* Build list of quotas to initialize... */ + if (IS_NOQUOTA(inode)) + goto out_err; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (type != -1 && cnt != type) continue; @@ -846,14 +925,16 @@ inode->i_flags |= S_QUOTA; } } +out_err: up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + return ret; } /* * Release all quotas referenced by inode * Transaction must be started at an entry */ -void dquot_drop(struct inode *inode) +int dquot_drop(struct inode *inode) { int cnt; @@ -866,9 +947,19 @@ } } up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + return 0; } /* + * Following four functions update i_blocks+i_bytes fields and + * quota information (together with appropriate checks) + * NOTE: We absolutely rely on the fact that caller dirties + * the inode (usually macros in quotaops.h care about this) and + * holds a handle for the current transaction so that dquot write and + * inode write go into the same transaction. + */ + +/* * This operation can block, but only after everything is updated */ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) @@ -876,8 +967,10 @@ int cnt, ret = NO_QUOTA; char warntype[MAXQUOTAS]; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) { +out_add: inode_add_bytes(inode, number); return QUOTA_OK; } @@ -885,10 +978,11 @@ warntype[cnt] = NOWARN; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */ + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + goto out_add; + } spin_lock(&dq_data_lock); - /* Now recheck reliably when holding dqptr_sem */ - if (IS_NOQUOTA(inode)) - goto add_bytes; for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) continue; @@ -900,11 +994,15 @@ continue; dquot_incr_space(inode->i_dquot[cnt], number); } -add_bytes: inode_add_bytes(inode, number); ret = QUOTA_OK; warn_put_all: spin_unlock(&dq_data_lock); + if (ret == QUOTA_OK) + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + if (inode->i_dquot[cnt]) + mark_dquot_dirty(inode->i_dquot[cnt]); flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; @@ -918,13 +1016,13 @@ int cnt, ret = NO_QUOTA; char warntype[MAXQUOTAS]; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) return QUOTA_OK; for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = NOWARN; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return QUOTA_OK; @@ -945,6 +1043,11 @@ ret = QUOTA_OK; warn_put_all: spin_unlock(&dq_data_lock); + if (ret == QUOTA_OK) + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + if (inode->i_dquot[cnt]) + mark_dquot_dirty(inode->i_dquot[cnt]); flush_warnings((struct dquot **)inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); return ret; @@ -953,46 +1056,55 @@ /* * This is a non-blocking operation. */ -void dquot_free_space(struct inode *inode, qsize_t number) +int dquot_free_space(struct inode *inode, qsize_t number) { unsigned int cnt; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) { +out_sub: inode_sub_bytes(inode, number); - return; + return QUOTA_OK; } down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - spin_lock(&dq_data_lock); /* Now recheck reliably when holding dqptr_sem */ - if (IS_NOQUOTA(inode)) - goto sub_bytes; + if (IS_NOQUOTA(inode)) { + up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + goto out_sub; + } + spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (inode->i_dquot[cnt] == NODQUOT) continue; dquot_decr_space(inode->i_dquot[cnt], number); } -sub_bytes: inode_sub_bytes(inode, number); spin_unlock(&dq_data_lock); + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + if (inode->i_dquot[cnt]) + mark_dquot_dirty(inode->i_dquot[cnt]); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + return QUOTA_OK; } /* * This is a non-blocking operation. */ -void dquot_free_inode(const struct inode *inode, unsigned long number) +int dquot_free_inode(const struct inode *inode, unsigned long number) { unsigned int cnt; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) - return; + return QUOTA_OK; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - return; + return QUOTA_OK; } spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1001,7 +1113,12 @@ dquot_decr_inodes(inode->i_dquot[cnt], number); } spin_unlock(&dq_data_lock); + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) + if (inode->i_dquot[cnt]) + mark_dquot_dirty(inode->i_dquot[cnt]); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); + return QUOTA_OK; } /* @@ -1018,7 +1135,8 @@ chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; char warntype[MAXQUOTAS]; - /* Solve deadlock when we recurse when holding dqptr_sem... */ + /* First test before acquiring semaphore - solves deadlocks when we + * re-enter the quota code and are already holding the semaphore */ if (IS_NOQUOTA(inode)) return QUOTA_OK; /* Clear the arrays */ @@ -1026,15 +1144,15 @@ transfer_to[cnt] = transfer_from[cnt] = NODQUOT; warntype[cnt] = NOWARN; } - down(&sb_dqopt(inode->i_sb)->dqonoff_sem); down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); /* Now recheck reliably when holding dqptr_sem */ if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); - up(&sb_dqopt(inode->i_sb)->dqonoff_sem); return QUOTA_OK; } - /* First build the transfer_to list - here we can block on reading of dquots... */ + /* First build the transfer_to list - here we can block on + * reading/instantiating of dquots. We know that the transaction for + * us was already started so we don't violate lock ranking here */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { switch (cnt) { case USRQUOTA: @@ -1082,7 +1200,13 @@ ret = QUOTA_OK; warn_put_all: spin_unlock(&dq_data_lock); - up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + /* Dirtify all the dquots - this can block when journalling */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (transfer_from[cnt]) + mark_dquot_dirty(transfer_from[cnt]); + if (transfer_to[cnt]) + mark_dquot_dirty(transfer_to[cnt]); + } flush_warnings(transfer_to, warntype); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1091,7 +1215,21 @@ if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT) dqput(transfer_to[cnt]); } - up(&sb_dqopt(inode->i_sb)->dqonoff_sem); + up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); + return ret; +} + +/* + * Write info of quota file to disk + */ +int dquot_commit_info(struct super_block *sb, int type) +{ + int ret; + struct quota_info *dqopt = sb_dqopt(sb); + + down(&dqopt->dqio_sem); + ret = dqopt->ops[type]->write_file_info(sb, type); + up(&dqopt->dqio_sem); return ret; } @@ -1099,22 +1237,18 @@ * Definitions of diskquota operations. */ struct dquot_operations dquot_operations = { - .initialize = dquot_initialize, /* mandatory */ - .drop = dquot_drop, /* mandatory */ + .initialize = dquot_initialize, + .drop = dquot_drop, .alloc_space = dquot_alloc_space, .alloc_inode = dquot_alloc_inode, .free_space = dquot_free_space, .free_inode = dquot_free_inode, .transfer = dquot_transfer, - .write_dquot = commit_dqblk + .write_dquot = dquot_commit, + .mark_dirty = dquot_mark_dquot_dirty, + .write_info = dquot_commit_info }; -/* Function used by filesystems for initializing the dquot_operations structure */ -void init_dquot_operations(struct dquot_operations *fsdqops) -{ - memcpy(fsdqops, &dquot_operations, sizeof(dquot_operations)); -} - static inline void set_enable_flags(struct quota_info *dqopt, int type) { switch (type) { @@ -1166,17 +1300,14 @@ * Now all dquots should be invalidated, all writes done so we should be only * users of the info. No locks needed. */ - if (info_dirty(&dqopt->info[cnt])) { - down(&dqopt->dqio_sem); - dqopt->ops[cnt]->write_file_info(sb, cnt); - up(&dqopt->dqio_sem); - } + if (info_dirty(&dqopt->info[cnt])) + sb->dq_op->write_info(sb, cnt); if (dqopt->ops[cnt]->free_file_info) dqopt->ops[cnt]->free_file_info(sb, cnt); put_quota_format(dqopt->info[cnt].dqi_format); fput(dqopt->files[cnt]); - dqopt->files[cnt] = (struct file *)NULL; + dqopt->files[cnt] = NULL; dqopt->info[cnt].dqi_flags = 0; dqopt->info[cnt].dqi_igrace = 0; dqopt->info[cnt].dqi_bgrace = 0; @@ -1187,33 +1318,30 @@ return 0; } -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path) +/* + * Turn quotas on on a device + */ + +/* Helper function when we already have file open */ +static int vfs_quota_on_file(struct file *f, int type, int format_id) { - struct file *f; + struct quota_format_type *fmt = find_quota_format(format_id); struct inode *inode; + struct super_block *sb = f->f_dentry->d_sb; struct quota_info *dqopt = sb_dqopt(sb); - struct quota_format_type *fmt = find_quota_format(format_id); - int error, cnt; struct dquot *to_drop[MAXQUOTAS]; + int error, cnt; unsigned int oldflags; if (!fmt) return -ESRCH; - f = filp_open(path, O_RDWR, 0600); - if (IS_ERR(f)) { - error = PTR_ERR(f); - goto out_fmt; - } error = -EIO; if (!f->f_op || !f->f_op->read || !f->f_op->write) - goto out_f; - error = security_quota_on(f); - if (error) - goto out_f; + goto out_fmt; inode = f->f_dentry->d_inode; error = -EACCES; if (!S_ISREG(inode->i_mode)) - goto out_f; + goto out_fmt; down(&dqopt->dqonoff_sem); if (sb_has_quota_enabled(sb, type)) { @@ -1235,7 +1363,7 @@ inode->i_flags &= ~S_QUOTA; up_write(&dqopt->dqptr_sem); /* We must put dquots outside of dqptr_sem because we may need to - * start transaction for write */ + * start transaction for dquot_release() */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (to_drop[cnt]) dqput(to_drop[cnt]); @@ -1262,14 +1390,58 @@ out_lock: up_write(&dqopt->dqptr_sem); up(&dqopt->dqonoff_sem); -out_f: - filp_close(f, NULL); out_fmt: put_quota_format(fmt); return error; } +/* Actual function called from quotactl() */ +int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path) +{ + struct file *f; + int error; + + f = filp_open(path, O_RDWR, 0600); + if (IS_ERR(f)) + return PTR_ERR(f); + error = security_quota_on(f); + if (error) + goto out_f; + error = vfs_quota_on_file(f, type, format_id); + if (!error) + return 0; +out_f: + filp_close(f, NULL); + return error; +} + +/* + * Function used by filesystems when filp_open() would fail (filesystem is + * being mounted now). We will use a private file structure. Caller is + * responsible that it's IO functions won't need vfsmnt structure or + * some dentry tricks... + */ +int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry) +{ + struct file *f; + int error; + + dget(dentry); /* Get a reference for struct file */ + f = dentry_open(dentry, NULL, O_RDWR); + if (IS_ERR(f)) { + error = PTR_ERR(f); + goto out_dentry; + } + error = vfs_quota_on_file(f, type, format_id); + if (!error) + return 0; + fput(f); +out_dentry: + dput(dentry); + return error; +} + /* Generic routine for getting common part of quota structure */ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) { @@ -1353,8 +1525,8 @@ clear_bit(DQ_FAKE_B, &dquot->dq_flags); else set_bit(DQ_FAKE_B, &dquot->dq_flags); - mark_dquot_dirty(dquot); spin_unlock(&dq_data_lock); + mark_dquot_dirty(dquot); } int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) @@ -1411,8 +1583,10 @@ mi->dqi_igrace = ii->dqi_igrace; if (ii->dqi_valid & IIF_FLAGS) mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK); - mark_info_dirty(mi); spin_unlock(&dq_data_lock); + mark_info_dirty(sb, type); + /* Force write to disk */ + sb->dq_op->write_info(sb, type); up(&sb_dqopt(sb)->dqonoff_sem); return 0; } @@ -1544,4 +1718,21 @@ EXPORT_SYMBOL(dqstats); EXPORT_SYMBOL(dq_list_lock); EXPORT_SYMBOL(dq_data_lock); -EXPORT_SYMBOL(init_dquot_operations); +EXPORT_SYMBOL(vfs_quota_on); +EXPORT_SYMBOL(vfs_quota_on_mount); +EXPORT_SYMBOL(vfs_quota_off); +EXPORT_SYMBOL(vfs_quota_sync); +EXPORT_SYMBOL(vfs_get_dqinfo); +EXPORT_SYMBOL(vfs_set_dqinfo); +EXPORT_SYMBOL(vfs_get_dqblk); +EXPORT_SYMBOL(vfs_set_dqblk); +EXPORT_SYMBOL(dquot_commit); +EXPORT_SYMBOL(dquot_commit_info); +EXPORT_SYMBOL(dquot_mark_dquot_dirty); +EXPORT_SYMBOL(dquot_initialize); +EXPORT_SYMBOL(dquot_drop); +EXPORT_SYMBOL(dquot_alloc_space); +EXPORT_SYMBOL(dquot_alloc_inode); +EXPORT_SYMBOL(dquot_free_space); +EXPORT_SYMBOL(dquot_free_inode); +EXPORT_SYMBOL(dquot_transfer); diff -Nru a/fs/efs/super.c b/fs/efs/super.c --- a/fs/efs/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/efs/super.c Sun Apr 18 13:42:41 2004 @@ -77,12 +77,19 @@ s->s_fs_info = NULL; } +static int efs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_RDONLY; + return 0; +} + static struct super_operations efs_superblock_operations = { .alloc_inode = efs_alloc_inode, .destroy_inode = efs_destroy_inode, .read_inode = efs_read_inode, .put_super = efs_put_super, .statfs = efs_statfs, + .remount_fs = efs_remount, }; static int __init init_efs_fs(void) { diff -Nru a/fs/exec.c b/fs/exec.c --- a/fs/exec.c Sun Apr 18 13:42:40 2004 +++ b/fs/exec.c Sun Apr 18 13:42:40 2004 @@ -609,7 +609,9 @@ newsig->group_stop_count = 0; newsig->curr_target = NULL; init_sigpending(&newsig->shared_pending); + INIT_LIST_HEAD(&newsig->posix_timers); + newsig->tty = oldsig->tty; newsig->pgrp = oldsig->pgrp; newsig->session = oldsig->session; newsig->leader = oldsig->leader; diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c --- a/fs/ext3/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/ext3/inode.c Sun Apr 18 13:42:41 2004 @@ -1358,8 +1358,6 @@ } if (!page_has_buffers(page)) { - if (!PageUptodate(page)) - buffer_error(); create_empty_buffers(page, inode->i_sb->s_blocksize, (1 << BH_Dirty)|(1 << BH_Uptodate)); } @@ -2772,9 +2770,28 @@ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { + handle_t *handle; + + /* (user+group)*(old+new) structure, inode write (sb, + * inode block, ? - but truncate inode update has it) */ + handle = ext3_journal_start(inode, 4*EXT3_QUOTA_INIT_BLOCKS+3); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + goto err_out; + } error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; - if (error) + if (error) { + ext3_journal_stop(handle); return error; + } + /* Update corresponding info in inode so that everything is in + * one transaction */ + if (attr->ia_valid & ATTR_UID) + inode->i_uid = attr->ia_uid; + if (attr->ia_valid & ATTR_GID) + inode->i_gid = attr->ia_gid; + error = ext3_mark_inode_dirty(handle, inode); + ext3_journal_stop(handle); } if (S_ISREG(inode->i_mode) && @@ -2853,7 +2870,9 @@ ret = 2 * (bpp + indirects) + 2; #ifdef CONFIG_QUOTA - ret += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; + /* We know that structure was already allocated during DQUOT_INIT so + * we will be updating only the data blocks + inodes */ + ret += 2*EXT3_QUOTA_TRANS_BLOCKS; #endif return ret; diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c --- a/fs/ext3/namei.c Sun Apr 18 13:42:41 2004 +++ b/fs/ext3/namei.c Sun Apr 18 13:42:41 2004 @@ -1631,7 +1631,8 @@ int err; handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + - EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + + 2*EXT3_QUOTA_INIT_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1661,7 +1662,8 @@ return -EINVAL; handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + - EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + + 2*EXT3_QUOTA_INIT_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1693,7 +1695,8 @@ return -EMLINK; handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + - EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + + 2*EXT3_QUOTA_INIT_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1972,6 +1975,9 @@ struct ext3_dir_entry_2 * de; handle_t *handle; + /* Initialize quotas before so that eventual writes go in + * separate transaction */ + DQUOT_INIT(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1985,7 +1991,6 @@ handle->h_sync = 1; inode = dentry->d_inode; - DQUOT_INIT(inode); retval = -EIO; if (le32_to_cpu(de->inode) != inode->i_ino) @@ -2029,6 +2034,9 @@ struct ext3_dir_entry_2 * de; handle_t *handle; + /* Initialize quotas before so that eventual writes go + * in separate transaction */ + DQUOT_INIT(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2042,7 +2050,6 @@ goto end_unlink; inode = dentry->d_inode; - DQUOT_INIT(inode); retval = -EIO; if (le32_to_cpu(de->inode) != inode->i_ino) @@ -2085,7 +2092,8 @@ return -ENAMETOOLONG; handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + - EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + + 2*EXT3_QUOTA_INIT_BLOCKS); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2170,6 +2178,10 @@ old_bh = new_bh = dir_bh = NULL; + /* Initialize quotas before so that eventual writes go + * in separate transaction */ + if (new_dentry->d_inode) + DQUOT_INIT(new_dentry->d_inode); handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); if (IS_ERR(handle)) @@ -2196,8 +2208,6 @@ if (!new_inode) { brelse (new_bh); new_bh = NULL; - } else { - DQUOT_INIT(new_inode); } } if (S_ISDIR(old_inode->i_mode)) { diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c --- a/fs/ext3/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/ext3/super.c Sun Apr 18 13:42:41 2004 @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #include #include "xattr.h" #include "acl.h" @@ -504,7 +507,43 @@ # define ext3_clear_inode NULL #endif -static struct dquot_operations ext3_qops; +#ifdef CONFIG_QUOTA + +#define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") +#define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) + +static int ext3_dquot_initialize(struct inode *inode, int type); +static int ext3_dquot_drop(struct inode *inode); +static int ext3_write_dquot(struct dquot *dquot); +static int ext3_mark_dquot_dirty(struct dquot *dquot); +static int ext3_write_info(struct super_block *sb, int type); +static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path); +static int ext3_quota_on_mount(struct super_block *sb, int type); +static int ext3_quota_off_mount(struct super_block *sb, int type); + +static struct dquot_operations ext3_quota_operations = { + .initialize = ext3_dquot_initialize, + .drop = ext3_dquot_drop, + .alloc_space = dquot_alloc_space, + .alloc_inode = dquot_alloc_inode, + .free_space = dquot_free_space, + .free_inode = dquot_free_inode, + .transfer = dquot_transfer, + .write_dquot = ext3_write_dquot, + .mark_dirty = ext3_mark_dquot_dirty, + .write_info = ext3_write_info +}; + +static struct quotactl_ops ext3_qctl_operations = { + .quota_on = ext3_quota_on, + .quota_off = vfs_quota_off, + .quota_sync = vfs_quota_sync, + .get_info = vfs_get_dqinfo, + .set_info = vfs_set_dqinfo, + .get_dqblk = vfs_get_dqblk, + .set_dqblk = vfs_set_dqblk +}; +#endif static struct super_operations ext3_sops = { .alloc_inode = ext3_alloc_inode, @@ -536,6 +575,8 @@ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload, Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, + Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_ignore, Opt_err, }; @@ -571,6 +612,12 @@ {Opt_data_journal, "data=journal"}, {Opt_data_ordered, "data=ordered"}, {Opt_data_writeback, "data=writeback"}, + {Opt_offusrjquota, "usrjquota="}, + {Opt_usrjquota, "usrjquota=%s"}, + {Opt_offgrpjquota, "grpjquota="}, + {Opt_grpjquota, "grpjquota=%s"}, + {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, + {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, {Opt_ignore, "grpquota"}, {Opt_ignore, "noquota"}, {Opt_ignore, "quota"}, @@ -598,13 +645,17 @@ return sb_block; } -static int parse_options (char * options, struct ext3_sb_info *sbi, +static int parse_options (char * options, struct super_block *sb, unsigned long * inum, int is_remount) { + struct ext3_sb_info *sbi = EXT3_SB(sb); char * p; substring_t args[MAX_OPT_ARGS]; int data_opt = 0; int option; +#ifdef CONFIG_QUOTA + int qtype; +#endif if (!options) return 1; @@ -763,6 +814,76 @@ sbi->s_mount_opt |= data_opt; } break; +#ifdef CONFIG_QUOTA + case Opt_usrjquota: + qtype = USRQUOTA; + goto set_qf_name; + case Opt_grpjquota: + qtype = GRPQUOTA; +set_qf_name: + if (sb_any_quota_enabled(sb)) { + printk(KERN_ERR + "EXT3-fs: Cannot change journalled " + "quota options when quota turned on.\n"); + return 0; + } + if (sbi->s_qf_names[qtype]) { + printk(KERN_ERR + "EXT3-fs: %s quota file already " + "specified.\n", QTYPE2NAME(qtype)); + return 0; + } + sbi->s_qf_names[qtype] = match_strdup(&args[0]); + if (!sbi->s_qf_names[qtype]) { + printk(KERN_ERR + "EXT3-fs: not enough memory for " + "storing quotafile name.\n"); + return 0; + } + if (strchr(sbi->s_qf_names[qtype], '/')) { + printk(KERN_ERR + "EXT3-fs: quotafile must be on " + "filesystem root.\n"); + kfree(sbi->s_qf_names[qtype]); + sbi->s_qf_names[qtype] = NULL; + return 0; + } + break; + case Opt_offusrjquota: + qtype = USRQUOTA; + goto clear_qf_name; + case Opt_offgrpjquota: + qtype = GRPQUOTA; +clear_qf_name: + if (sb_any_quota_enabled(sb)) { + printk(KERN_ERR "EXT3-fs: Cannot change " + "journalled quota options when " + "quota turned on.\n"); + return 0; + } + if (sbi->s_qf_names[qtype]) { + kfree(sbi->s_qf_names[qtype]); + sbi->s_qf_names[qtype] = NULL; + } + break; + case Opt_jqfmt_vfsold: + sbi->s_jquota_fmt = QFMT_VFS_OLD; + break; + case Opt_jqfmt_vfsv0: + sbi->s_jquota_fmt = QFMT_VFS_V0; + break; +#else + case Opt_usrjquota: + case Opt_grpjquota: + case Opt_offusrjquota: + case Opt_offgrpjquota: + case Opt_jqfmt_vfsold: + case Opt_jqfmt_vfsv0: + printk(KERN_ERR + "EXT3-fs: journalled quota options not " + "supported.\n"); + break; +#endif case Opt_abort: set_opt(sbi->s_mount_opt, ABORT); break; @@ -775,6 +896,13 @@ return 0; } } +#ifdef CONFIG_QUOTA + if (!sbi->s_jquota_fmt && (sbi->s_qf_names[0] || sbi->s_qf_names[1])) { + printk(KERN_ERR + "EXT3-fs: journalled quota format not specified.\n"); + return 0; + } +#endif return 1; } @@ -934,6 +1062,9 @@ { unsigned int s_flags = sb->s_flags; int nr_orphans = 0, nr_truncates = 0; +#ifdef CONFIG_QUOTA + int i; +#endif if (!es->s_last_orphan) { jbd_debug(4, "no orphan inodes to clean up\n"); return; @@ -953,6 +1084,20 @@ sb->s_id); sb->s_flags &= ~MS_RDONLY; } +#ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sb->s_flags |= MS_ACTIVE; + /* Turn on quotas so that they are updated correctly */ + for (i = 0; i < MAXQUOTAS; i++) { + if (EXT3_SB(sb)->s_qf_names[i]) { + int ret = ext3_quota_on_mount(sb, i); + if (ret < 0) + printk(KERN_ERR + "EXT3-fs: Cannot turn on journalled " + "quota: error %d\n", ret); + } + } +#endif while (es->s_last_orphan) { struct inode *inode; @@ -964,6 +1109,7 @@ } list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); + DQUOT_INIT(inode); if (inode->i_nlink) { printk(KERN_DEBUG "%s: truncating inode %ld to %Ld bytes\n", @@ -991,6 +1137,13 @@ if (nr_truncates) printk(KERN_INFO "EXT3-fs: %s: %d truncate%s cleaned up\n", sb->s_id, PLURAL(nr_truncates)); +#ifdef CONFIG_QUOTA + /* Turn quotas off */ + for (i = 0; i < MAXQUOTAS; i++) { + if (sb_dqopt(sb)->files[i]) + ext3_quota_off_mount(sb, i); + } +#endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ } @@ -1124,7 +1277,7 @@ sbi->s_resuid = le16_to_cpu(es->s_def_resuid); sbi->s_resgid = le16_to_cpu(es->s_def_resgid); - if (!parse_options ((char *) data, sbi, &journal_inum, 0)) + if (!parse_options ((char *) data, sb, &journal_inum, 0)) goto failed_mount; sb->s_flags |= MS_ONE_SECOND; @@ -1303,7 +1456,10 @@ */ sb->s_op = &ext3_sops; sb->s_export_op = &ext3_export_ops; - sb->dq_op = &ext3_qops; +#ifdef CONFIG_QUOTA + sb->s_qcop = &ext3_qctl_operations; + sb->dq_op = &ext3_quota_operations; +#endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ sb->s_root = 0; @@ -1413,6 +1569,12 @@ brelse(sbi->s_group_desc[i]); kfree(sbi->s_group_desc); failed_mount: +#ifdef CONFIG_QUOTA + for (i = 0; i < MAXQUOTAS; i++) { + if (sbi->s_qf_names[i]) + kfree(sbi->s_qf_names[i]); + } +#endif ext3_blkdev_remove(sbi); brelse(bh); out_fail: @@ -1839,7 +2001,7 @@ /* * Allow the "check" option to be passed as a remount option. */ - if (!parse_options(data, sbi, &tmp, 1)) + if (!parse_options(data, sb, &tmp, 1)) return -EINVAL; if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) @@ -1959,70 +2121,152 @@ #ifdef CONFIG_QUOTA -/* Blocks: (2 data blocks) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ -#define EXT3_OLD_QFMT_BLOCKS 11 -/* Blocks: quota info + (4 pointer blocks + 1 entry block) * (3 indirect + 1 descriptor + 1 bitmap) + superblock */ -#define EXT3_V0_QFMT_BLOCKS 27 - -static int (*old_write_dquot)(struct dquot *dquot); -static void (*old_drop_dquot)(struct inode *inode); - -static int fmt_to_blocks(int fmt) -{ - switch (fmt) { - case QFMT_VFS_OLD: - return EXT3_OLD_QFMT_BLOCKS; - case QFMT_VFS_V0: - return EXT3_V0_QFMT_BLOCKS; - } - return EXT3_MAX_TRANS_DATA; +static inline struct inode *dquot_to_inode(struct dquot *dquot) +{ + return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]->f_dentry->d_inode; } -static int ext3_write_dquot(struct dquot *dquot) +static int ext3_dquot_initialize(struct inode *inode, int type) { - int nblocks; - int ret; - int err; handle_t *handle; - struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); - struct inode *qinode; + int ret, err; - nblocks = fmt_to_blocks(dqopt->info[dquot->dq_type].dqi_format->qf_fmt_id); - qinode = dqopt->files[dquot->dq_type]->f_dentry->d_inode; - handle = ext3_journal_start(qinode, nblocks); - if (IS_ERR(handle)) { - ret = PTR_ERR(handle); - goto out; - } - ret = old_write_dquot(dquot); + /* We may create quota structure so we need to reserve enough blocks */ + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ret = dquot_initialize(inode, type); err = ext3_journal_stop(handle); - if (ret == 0) + if (!ret) ret = err; -out: return ret; } -static void ext3_drop_dquot(struct inode *inode) +static int ext3_dquot_drop(struct inode *inode) { - int nblocks, type; - struct quota_info *dqopt = sb_dqopt(inode->i_sb); handle_t *handle; + int ret, err; - for (type = 0; type < MAXQUOTAS; type++) { - if (sb_has_quota_enabled(inode->i_sb, type)) - break; - } - if (type < MAXQUOTAS) - nblocks = fmt_to_blocks(dqopt->info[type].dqi_format->qf_fmt_id); + /* We may delete quota structure so we need to reserve enough blocks */ + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ret = dquot_drop(inode); + err = ext3_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + +static int ext3_write_dquot(struct dquot *dquot) +{ + int ret, err; + handle_t *handle; + + handle = ext3_journal_start(dquot_to_inode(dquot), + EXT3_QUOTA_TRANS_BLOCKS); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ret = dquot_commit(dquot); + err = ext3_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + +static int ext3_mark_dquot_dirty(struct dquot * dquot) +{ + /* Are we journalling quotas? */ + if (EXT3_SB(dquot->dq_sb)->s_qf_names[0] || + EXT3_SB(dquot->dq_sb)->s_qf_names[1]) + return ext3_write_dquot(dquot); else - nblocks = 0; /* No quota => no drop */ - handle = ext3_journal_start(inode, 2*nblocks); + return dquot_mark_dquot_dirty(dquot); +} + +static int ext3_write_info(struct super_block *sb, int type) +{ + int ret, err; + handle_t *handle; + + /* Data block + inode block */ + handle = ext3_journal_start(sb->s_root->d_inode, 2); if (IS_ERR(handle)) - return; - old_drop_dquot(inode); - ext3_journal_stop(handle); - return; + return PTR_ERR(handle); + ret = dquot_commit_info(sb, type); + err = ext3_journal_stop(handle); + if (!ret) + ret = err; + return ret; +} + +/* + * Turn on quotas during mount time - we need to find + * the quota file and such... + */ +static int ext3_quota_on_mount(struct super_block *sb, int type) +{ + int err; + struct dentry *dentry; + struct qstr name = { .name = EXT3_SB(sb)->s_qf_names[type], + .hash = 0, + .len = strlen(EXT3_SB(sb)->s_qf_names[type])}; + + dentry = lookup_hash(&name, sb->s_root); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + err = vfs_quota_on_mount(type, EXT3_SB(sb)->s_jquota_fmt, dentry); + if (err) + dput(dentry); + /* We keep the dentry reference if everything went ok - we drop it + * on quota_off time */ + return err; +} + +/* Turn quotas off during mount time */ +static int ext3_quota_off_mount(struct super_block *sb, int type) +{ + int err; + struct dentry *dentry; + + dentry = sb_dqopt(sb)->files[type]->f_dentry; + err = vfs_quota_off_mount(sb, type); + /* We invalidate dentry - it has at least wrong hash... */ + d_invalidate(dentry); + dput(dentry); + return err; +} + +/* + * Standard function to be called on quota_on + */ +static int ext3_quota_on(struct super_block *sb, int type, int format_id, + char *path) +{ + int err; + struct nameidata nd; + + /* Not journalling quota? */ + if (!EXT3_SB(sb)->s_qf_names[0] && !EXT3_SB(sb)->s_qf_names[1]) + return vfs_quota_on(sb, type, format_id, path); + err = path_lookup(path, LOOKUP_FOLLOW, &nd); + if (err) + return err; + /* Quotafile not on the same filesystem? */ + if (nd.mnt->mnt_sb != sb) + return -EXDEV; + /* Quotafile not of fs root? */ + if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode) + printk(KERN_WARNING + "EXT3-fs: Quota file not on filesystem root. " + "Journalled quota will not work.\n"); + if (!ext3_should_journal_data(nd.dentry->d_inode)) + printk(KERN_WARNING "EXT3-fs: Quota file does not have " + "data-journalling. Journalled quota will not work.\n"); + path_release(&nd); + return vfs_quota_on(sb, type, format_id, path); } + #endif static struct super_block *ext3_get_sb(struct file_system_type *fs_type, @@ -2047,13 +2291,6 @@ err = init_inodecache(); if (err) goto out1; -#ifdef CONFIG_QUOTA - init_dquot_operations(&ext3_qops); - old_write_dquot = ext3_qops.write_dquot; - old_drop_dquot = ext3_qops.drop; - ext3_qops.write_dquot = ext3_write_dquot; - ext3_qops.drop = ext3_drop_dquot; -#endif err = register_filesystem(&ext3_fs_type); if (err) goto out; diff -Nru a/fs/fat/inode.c b/fs/fat/inode.c --- a/fs/fat/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/fat/inode.c Sun Apr 18 13:42:41 2004 @@ -734,6 +734,12 @@ printk(KERN_INFO "fat_inode_cache: not all structures were freed\n"); } +static int fat_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + static struct super_operations fat_sops = { .alloc_inode = fat_alloc_inode, .destroy_inode = fat_destroy_inode, @@ -742,6 +748,7 @@ .put_super = fat_put_super, .statfs = fat_statfs, .clear_inode = fat_clear_inode, + .remount_fs = fat_remount, .read_inode = make_bad_inode, diff -Nru a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c --- a/fs/freevxfs/vxfs_super.c Sun Apr 18 13:42:41 2004 +++ b/fs/freevxfs/vxfs_super.c Sun Apr 18 13:42:41 2004 @@ -56,12 +56,14 @@ static void vxfs_put_super(struct super_block *); static int vxfs_statfs(struct super_block *, struct kstatfs *); +static int vxfs_remount(struct super_block *, int *, char *); static struct super_operations vxfs_super_ops = { .read_inode = vxfs_read_inode, .put_inode = vxfs_put_inode, .put_super = vxfs_put_super, .statfs = vxfs_statfs, + .remount_fs = vxfs_remount, }; /** @@ -118,6 +120,12 @@ bufp->f_ffree = infp->vsi_raw->vs_ifree; bufp->f_namelen = VXFS_NAMELEN; + return 0; +} + +static int vxfs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_RDONLY; return 0; } diff -Nru a/fs/hfs/super.c b/fs/hfs/super.c --- a/fs/hfs/super.c Sun Apr 18 13:42:40 2004 +++ b/fs/hfs/super.c Sun Apr 18 13:42:40 2004 @@ -94,6 +94,7 @@ int hfs_remount(struct super_block *sb, int *flags, char *data) { + *flags |= MS_NODIRATIME; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (!(*flags & MS_RDONLY)) { diff -Nru a/fs/isofs/inode.c b/fs/isofs/inode.c --- a/fs/isofs/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/isofs/inode.c Sun Apr 18 13:42:41 2004 @@ -119,12 +119,20 @@ printk(KERN_INFO "iso_inode_cache: not all structures were freed\n"); } +static int isofs_remount(struct super_block *sb, int *flags, char *data) +{ + /* we probably want a lot more here */ + *flags |= MS_RDONLY; + return 0; +} + static struct super_operations isofs_sops = { .alloc_inode = isofs_alloc_inode, .destroy_inode = isofs_destroy_inode, .read_inode = isofs_read_inode, .put_super = isofs_put_super, .statfs = isofs_statfs, + .remount_fs = isofs_remount, }; /* the export_operations structure for describing diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c --- a/fs/jbd/transaction.c Sun Apr 18 13:42:40 2004 +++ b/fs/jbd/transaction.c Sun Apr 18 13:42:40 2004 @@ -1111,26 +1111,21 @@ * I _think_ we're OK here with SMP barriers - a mistaken decision will * result in this test being false, so we go in and take the locks. */ - if (jh->b_transaction == handle->h_transaction && - jh->b_jlist == BJ_Metadata) { + if (jh->b_transaction == transaction && jh->b_jlist == BJ_Metadata) { JBUFFER_TRACE(jh, "fastpath"); J_ASSERT_JH(jh, jh->b_transaction == journal->j_running_transaction); goto out_unlock_bh; } - spin_lock(&journal->j_list_lock); set_buffer_jbddirty(bh); - J_ASSERT_JH(jh, jh->b_transaction != NULL); - /* * Metadata already on the current transaction list doesn't * need to be filed. Metadata on another transaction's list must * be committing, and will be refiled once the commit completes: * leave it alone for now. */ - if (jh->b_transaction != transaction) { JBUFFER_TRACE(jh, "already on other transaction"); J_ASSERT_JH(jh, jh->b_transaction == @@ -1138,17 +1133,15 @@ J_ASSERT_JH(jh, jh->b_next_transaction == transaction); /* And this case is illegal: we can't reuse another * transaction's data buffer, ever. */ - /* FIXME: writepage() should be journalled */ - goto out_unlock_list; + goto out_unlock_bh; } /* That test should have eliminated the following case: */ J_ASSERT_JH(jh, jh->b_frozen_data == 0); JBUFFER_TRACE(jh, "file as BJ_Metadata"); + spin_lock(&journal->j_list_lock); __journal_file_buffer(jh, handle->h_transaction, BJ_Metadata); - -out_unlock_list: spin_unlock(&journal->j_list_lock); out_unlock_bh: jbd_unlock_bh_state(bh); diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c --- a/fs/jffs/inode-v23.c Sun Apr 18 13:42:41 2004 +++ b/fs/jffs/inode-v23.c Sun Apr 18 13:42:41 2004 @@ -1771,6 +1771,12 @@ unlock_kernel(); } +static int jffs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + static struct super_operations jffs_ops = { .read_inode = jffs_read_inode, @@ -1778,6 +1784,7 @@ .put_super = jffs_put_super, .write_super = jffs_write_super, .statfs = jffs_statfs, + .remount_fs = jffs_remount, }; static struct super_block *jffs_get_sb(struct file_system_type *fs_type, diff -Nru a/fs/jffs2/fs.c b/fs/jffs2/fs.c --- a/fs/jffs2/fs.c Sun Apr 18 13:42:41 2004 +++ b/fs/jffs2/fs.c Sun Apr 18 13:42:41 2004 @@ -350,7 +350,7 @@ if (!(*flags & MS_RDONLY)) jffs2_start_garbage_collect_thread(c); - sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY); + *flags |= MS_NOATIME; return 0; } diff -Nru a/fs/jffs2/super.c b/fs/jffs2/super.c --- a/fs/jffs2/super.c Sun Apr 18 13:42:40 2004 +++ b/fs/jffs2/super.c Sun Apr 18 13:42:40 2004 @@ -129,7 +129,7 @@ mtd->index, mtd->name)); sb->s_op = &jffs2_super_operations; - sb->s_flags |= MS_NODIRATIME; + sb->s_flags |= MS_NOATIME; ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0); diff -Nru a/fs/mpage.c b/fs/mpage.c --- a/fs/mpage.c Sun Apr 18 13:42:40 2004 +++ b/fs/mpage.c Sun Apr 18 13:42:40 2004 @@ -485,8 +485,7 @@ break; block_in_file++; } - if (page_block == 0) - buffer_error(); + BUG_ON(page_block == 0); first_unmapped = page_block; diff -Nru a/fs/namespace.c b/fs/namespace.c --- a/fs/namespace.c Sun Apr 18 13:42:41 2004 +++ b/fs/namespace.c Sun Apr 18 13:42:41 2004 @@ -777,7 +777,7 @@ mnt_flags |= MNT_NODEV; if (flags & MS_NOEXEC) mnt_flags |= MNT_NOEXEC; - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); + flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE); /* ... and get the mountpoint */ retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); diff -Nru a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c --- a/fs/ncpfs/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/ncpfs/inode.c Sun Apr 18 13:42:41 2004 @@ -85,6 +85,12 @@ printk(KERN_INFO "ncp_inode_cache: not all structures were freed\n"); } +static int ncp_remount(struct super_block *sb, int *flags, char* data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + static struct super_operations ncp_sops = { .alloc_inode = ncp_alloc_inode, @@ -93,6 +99,7 @@ .delete_inode = ncp_delete_inode, .put_super = ncp_put_super, .statfs = ncp_statfs, + .remount_fs = ncp_remount, }; extern struct dentry_operations ncp_root_dentry_operations; diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c --- a/fs/nfsd/nfs4proc.c Sun Apr 18 13:42:41 2004 +++ b/fs/nfsd/nfs4proc.c Sun Apr 18 13:42:41 2004 @@ -66,10 +66,31 @@ } static int +do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) +{ + int accmode, status; + + if (open->op_truncate && + !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) + return nfserr_inval; + + accmode = MAY_NOP; + if (open->op_share_access & NFS4_SHARE_ACCESS_READ) + accmode = MAY_READ; + if (open->op_share_deny & NFS4_SHARE_ACCESS_WRITE) + accmode |= (MAY_WRITE | MAY_TRUNC); + accmode |= MAY_OWNER_OVERRIDE; + + status = fh_verify(rqstp, current_fh, S_IFREG, accmode); + + return status; +} + +static int do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { struct svc_fh resfh; - int accmode, status; + int status; fh_init(&resfh, NFS4_FHSIZE); open->op_truncate = 0; @@ -92,6 +113,8 @@ if (!status) { set_change_info(&open->op_cinfo, current_fh); + + /* set reply cache */ fh_dup2(current_fh, &resfh); /* XXXJBF: keep a saved svc_fh struct instead?? */ open->op_stateowner->so_replay.rp_openfh_len = @@ -100,30 +123,66 @@ &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size); - accmode = MAY_NOP; - if (open->op_share_access & NFS4_SHARE_ACCESS_READ) - accmode = MAY_READ; - if (open->op_share_deny & NFS4_SHARE_ACCESS_WRITE) - accmode |= (MAY_WRITE | MAY_TRUNC); - accmode |= MAY_OWNER_OVERRIDE; - status = fh_verify(rqstp, current_fh, S_IFREG, accmode); + status = do_open_permission(rqstp, current_fh, open); } fh_put(&resfh); return status; } +static int +do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) +{ + int status; + + dprintk("NFSD: do_open_fhandle\n"); + + /* we don't know the target directory, and therefore can not + * set the change info + */ + + memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info)); + + /* set replay cache */ + open->op_stateowner->so_replay.rp_openfh_len = current_fh->fh_handle.fh_size; + memcpy(open->op_stateowner->so_replay.rp_openfh, + ¤t_fh->fh_handle.fh_base, + current_fh->fh_handle.fh_size); + + open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) && + !open->op_iattr.ia_size; + + status = do_open_permission(rqstp, current_fh, open); + + return status; +} + + +/* + * nfs4_unlock_state() called in encode + */ static inline int nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { int status; - dprintk("NFSD: nfsd4_open filename %.*s\n", - (int)open->op_fname.len, open->op_fname.data); + dprintk("NFSD: nfsd4_open filename %.*s op_stateowner %p\n", + (int)open->op_fname.len, open->op_fname.data, + open->op_stateowner); + + if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) + return nfserr_grace; + + if (nfs4_in_no_grace() && + open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) + return nfserr_no_grace; /* This check required by spec. */ if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) return nfserr_inval; + open->op_stateowner = NULL; + nfs4_lock_state(); + /* check seqid for replay. set nfs4_owner */ status = nfsd4_process_open1(open); if (status == NFSERR_REPLAY_ME) { @@ -141,16 +200,30 @@ } if (status) return status; + if (open->op_claim_type == NFS4_OPEN_CLAIM_NULL) { /* * This block of code will (1) set CURRENT_FH to the file being opened, * creating it if necessary, (2) set open->op_cinfo, * (3) set open->op_truncate if the file is to be truncated * after opening, (4) do permission checking. */ - status = do_open_lookup(rqstp, current_fh, open); - if (status) - return status; - + status = do_open_lookup(rqstp, current_fh, open); + if (status) + return status; + } else if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { + /* + * The CURRENT_FH is already set to the file being opened. This + * block of code will (1) set open->op_cinfo, (2) set + * open->op_truncate if the file is to be truncated after opening, + * (3) do permission checking. + */ + status = do_open_fhandle(rqstp, current_fh, open); + if (status) + return status; + } else { + printk("NFSD: unsupported OPEN claim type\n"); + return nfserr_inval; + } /* * nfsd4_process_open2() does the actual opening of the file. If * successful, it (1) truncates the file if open->op_truncate was @@ -187,9 +260,14 @@ static inline int nfsd4_putrootfh(struct svc_rqst *rqstp, struct svc_fh *current_fh) { + int status; + fh_put(current_fh); - return exp_pseudoroot(rqstp->rq_client, current_fh, + status = exp_pseudoroot(rqstp->rq_client, current_fh, &rqstp->rq_chandle); + if (!status) + status = nfsd_setuser(rqstp, current_fh->fh_export); + return status; } static inline int @@ -402,6 +480,8 @@ int status; /* no need to check permission - this will be done in nfsd_read() */ + if (nfs4_in_grace()) + return nfserr_grace; if (read->rd_offset >= OFFSET_MAX) return nfserr_inval; @@ -448,6 +528,9 @@ static inline int nfsd4_readdir(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_readdir *readdir) { + u64 cookie = readdir->rd_cookie; + static const nfs4_verifier zeroverf; + /* no need to check permission - this will be done in nfsd_readdir() */ if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1) @@ -456,7 +539,8 @@ readdir->rd_bmval[0] &= NFSD_SUPPORTED_ATTRS_WORD0; readdir->rd_bmval[1] &= NFSD_SUPPORTED_ATTRS_WORD1; - if (readdir->rd_cookie > ~(u32)0) + if ((cookie > ~(u32)0) || (cookie == 1) || (cookie == 2) || + (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE))) return nfserr_bad_cookie; readdir->rd_rqstp = rqstp; @@ -521,10 +605,13 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) { struct nfs4_stateid *stp; - int status = nfserr_nofilehandle; + int status = nfs_ok; + + if (nfs4_in_grace()) + return nfserr_grace; if (!current_fh->fh_dentry) - goto out; + return nfserr_nofilehandle; status = nfs_ok; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { @@ -563,6 +650,9 @@ u32 *p; int status = nfs_ok; + if (nfs4_in_grace()) + return nfserr_grace; + /* no need to check permission - this will be done in nfsd_write() */ if (write->wr_offset >= OFFSET_MAX) @@ -757,7 +847,9 @@ break; case OP_CLOSE: op->status = nfsd4_close(rqstp, ¤t_fh, &op->u.close); - op->replay = &op->u.close.cl_stateowner->so_replay; + if (op->u.close.cl_stateowner) + op->replay = + &op->u.close.cl_stateowner->so_replay; break; case OP_COMMIT: op->status = nfsd4_commit(rqstp, ¤t_fh, &op->u.commit); @@ -776,13 +868,18 @@ break; case OP_LOCK: op->status = nfsd4_lock(rqstp, ¤t_fh, &op->u.lock); - op->replay = &op->u.lock.lk_stateowner->so_replay; + if (op->u.lock.lk_stateowner) + op->replay = + &op->u.lock.lk_stateowner->so_replay; break; case OP_LOCKT: op->status = nfsd4_lockt(rqstp, ¤t_fh, &op->u.lockt); break; case OP_LOCKU: op->status = nfsd4_locku(rqstp, ¤t_fh, &op->u.locku); + if (op->u.locku.lu_stateowner) + op->replay = + &op->u.locku.lu_stateowner->so_replay; break; case OP_LOOKUP: op->status = nfsd4_lookup(rqstp, ¤t_fh, &op->u.lookup); @@ -797,15 +894,21 @@ break; case OP_OPEN: op->status = nfsd4_open(rqstp, ¤t_fh, &op->u.open); - op->replay = &op->u.open.op_stateowner->so_replay; + if (op->u.open.op_stateowner) + op->replay = + &op->u.open.op_stateowner->so_replay; break; case OP_OPEN_CONFIRM: op->status = nfsd4_open_confirm(rqstp, ¤t_fh, &op->u.open_confirm); - op->replay = &op->u.open_confirm.oc_stateowner->so_replay; + if (op->u.open_confirm.oc_stateowner) + op->replay = + &op->u.open_confirm.oc_stateowner->so_replay; break; case OP_OPEN_DOWNGRADE: op->status = nfsd4_open_downgrade(rqstp, ¤t_fh, &op->u.open_downgrade); - op->replay = &op->u.open_downgrade.od_stateowner->so_replay; + if (op->u.open_downgrade.od_stateowner) + op->replay = + &op->u.open_downgrade.od_stateowner->so_replay; break; case OP_PUTFH: op->status = nfsd4_putfh(rqstp, ¤t_fh, &op->u.putfh); diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c --- a/fs/nfsd/nfs4state.c Sun Apr 18 13:42:41 2004 +++ b/fs/nfsd/nfs4state.c Sun Apr 18 13:42:41 2004 @@ -52,6 +52,7 @@ /* Globals */ time_t boot_time; +static time_t grace_end = 0; static u32 current_clientid = 1; static u32 current_ownerid; static u32 current_fileid; @@ -89,6 +90,9 @@ down(&client_sema); } +/* + * nfs4_unlock_state(); called in encode + */ void nfs4_unlock_state(void) { @@ -136,12 +140,16 @@ * * client_lru holds client queue ordered by nfs4_client.cl_time * for lease renewal. + * + * close_lru holds (open) stateowner queue ordered by nfs4_stateowner.so_time + * for last close replay. */ static struct list_head conf_id_hashtbl[CLIENT_HASH_SIZE]; static struct list_head conf_str_hashtbl[CLIENT_HASH_SIZE]; static struct list_head unconf_str_hashtbl[CLIENT_HASH_SIZE]; static struct list_head unconf_id_hashtbl[CLIENT_HASH_SIZE]; static struct list_head client_lru; +static struct list_head close_lru; static inline void renew_client(struct nfs4_client *clp) @@ -376,7 +384,6 @@ unsigned int strhashval; struct nfs4_client * conf, * unconf, * new, * clp; int status; - struct list_head *pos, *next; status = nfserr_inval; if (!check_name(clname)) @@ -391,8 +398,7 @@ conf = NULL; nfs4_lock_state(); - list_for_each_safe(pos, next, &conf_str_hashtbl[strhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_strhash); + list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) { if (!cmp_name(&clp->cl_name, &clname)) continue; /* @@ -422,8 +428,7 @@ break; } unconf = NULL; - list_for_each_safe(pos, next, &unconf_str_hashtbl[strhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_strhash); + list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) { if (!cmp_name(&clp->cl_name, &clname)) continue; /* cl_name match from a previous SETCLIENTID operation */ @@ -549,7 +554,6 @@ struct nfs4_client *clp, *conf = NULL, *unconf = NULL; nfs4_verifier confirm = setclientid_confirm->sc_confirm; clientid_t * clid = &setclientid_confirm->sc_clientid; - struct list_head *pos, *next; int status; status = nfserr_stale_clientid; @@ -562,8 +566,7 @@ idhashval = clientid_hashval(clid->cl_id); nfs4_lock_state(); - list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_idhash); + list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { if (!cmp_clid(&clp->cl_clientid, clid)) continue; @@ -582,8 +585,7 @@ conf = clp; break; } - list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_idhash); + list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) { if (!cmp_clid(&clp->cl_clientid, clid)) continue; status = nfserr_inval; @@ -774,6 +776,8 @@ INIT_LIST_HEAD(&sop->so_perclient); INIT_LIST_HEAD(&sop->so_perfilestate); INIT_LIST_HEAD(&sop->so_perlockowner); /* not used */ + INIT_LIST_HEAD(&sop->so_close_lru); + sop->so_time = 0; list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]); list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]); list_add(&sop->so_perclient, &clp->cl_perclient); @@ -814,6 +818,7 @@ list_del(&sop->so_strhash); list_del(&sop->so_perclient); list_del(&sop->so_perlockowner); + list_del(&sop->so_close_lru); del_perclient++; while (!list_empty(&sop->so_perfilestate)) { stp = list_entry(sop->so_perfilestate.next, @@ -882,6 +887,19 @@ } void +move_to_close_lru(struct nfs4_stateowner *sop) +{ + dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop); + /* remove stateowner from all other hash lists except perclient */ + list_del_init(&sop->so_idhash); + list_del_init(&sop->so_strhash); + list_del_init(&sop->so_perlockowner); + + list_add_tail(&sop->so_close_lru, &close_lru); + sop->so_time = get_seconds(); +} + +void release_state_owner(struct nfs4_stateid *stp, struct nfs4_stateowner **sopp, int flag) { @@ -890,16 +908,13 @@ dprintk("NFSD: release_state_owner\n"); release_stateid(stp, flag); - /* - * release unused nfs4_stateowners. - * XXX will need to be placed on an open_stateid_lru list to be + + /* place unused nfs4_stateowners on so_close_lru list to be * released by the laundromat service after the lease period * to enable us to handle CLOSE replay */ - if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) { - release_stateowner(sop); - *sopp = NULL; - } + if (sop->so_confirmed && list_empty(&sop->so_perfilestate)) + move_to_close_lru(sop); /* unused nfs4_file's are releseed. XXX slab cache? */ if (list_empty(&fp->fi_perfile)) { release_file(fp); @@ -916,11 +931,9 @@ /* search ownerstr_hashtbl[] for owner */ static int find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open, struct nfs4_stateowner **op) { - struct list_head *pos, *next; struct nfs4_stateowner *local = NULL; - list_for_each_safe(pos, next, &ownerstr_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateowner, so_strhash); + list_for_each_entry(local, &ownerstr_hashtbl[hashval], so_strhash) { if(!cmp_owner_str(local, &open->op_owner, &open->op_clientid)) continue; *op = local; @@ -933,12 +946,10 @@ static int verify_clientid(struct nfs4_client **client, clientid_t *clid) { - struct list_head *pos, *next; struct nfs4_client *clp; unsigned int idhashval = clientid_hashval(clid->cl_id); - list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_idhash); + list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { if (!cmp_clid(&clp->cl_clientid, clid)) continue; *client = clp; @@ -951,11 +962,9 @@ /* search file_hashtbl[] for file */ static int find_file(unsigned int hashval, struct inode *ino, struct nfs4_file **fp) { - struct list_head *pos, *next; struct nfs4_file *local = NULL; - list_for_each_safe(pos, next, &file_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_file, fi_hash); + list_for_each_entry(local, &file_hashtbl[hashval], fi_hash) { if (local->fi_inode == ino) { *fp = local; return(1); @@ -1011,15 +1020,13 @@ unsigned int fi_hashval; struct nfs4_file *fp; struct nfs4_stateid *stp; - struct list_head *pos, *next; dprintk("NFSD: nfs4_share_conflict\n"); fi_hashval = file_hashval(ino); if (find_file(fi_hashval, ino, &fp)) { /* Search for conflicting share reservations */ - list_for_each_safe(pos, next, &fp->fi_perfile) { - stp = list_entry(pos, struct nfs4_stateid, st_perfile); + list_for_each_entry(stp, &fp->fi_perfile, st_perfile) { if (test_bit(deny_type, &stp->st_deny_bmap) || test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap)) return nfserr_share_denied; @@ -1066,6 +1073,8 @@ * notfound: * verify clientid * create new owner + * + * called with nfs4_lock_state() held. */ int nfsd4_process_open1(struct nfsd4_open *open) @@ -1082,9 +1091,8 @@ status = nfserr_stale_clientid; if (STALE_CLIENTID(&open->op_clientid)) - goto out; + return status; - nfs4_lock_state(); strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); if (find_openstateowner_str(strhashval, open, &sop)) { open->op_stateowner = sop; @@ -1104,7 +1112,7 @@ } /* replay: indicate to calling function */ status = NFSERR_REPLAY_ME; - goto out; + return status; } if (sop->so_confirmed) { if (open->op_seqid == sop->so_seqid + 1) { @@ -1142,25 +1150,27 @@ renew: renew_client(sop->so_client); out: - nfs4_unlock_state(); + if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) + status = nfserr_reclaim_bad; return status; } - +/* + * called with nfs4_lock_state() held. + */ int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open) { struct iattr iattr; struct nfs4_stateowner *sop = open->op_stateowner; - struct nfs4_file *fp; + struct nfs4_file *fp = NULL; struct inode *ino; unsigned int fi_hashval; - struct list_head *pos, *next; struct nfs4_stateid *stq, *stp = NULL; int status; status = nfserr_resource; if (!sop) - goto out; + return status; ino = current_fh->fh_dentry->d_inode; @@ -1168,13 +1178,11 @@ if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) goto out; - nfs4_lock_state(); fi_hashval = file_hashval(ino); if (find_file(fi_hashval, ino, &fp)) { /* Search for conflicting share reservations */ status = nfserr_share_denied; - list_for_each_safe(pos, next, &fp->fi_perfile) { - stq = list_entry(pos, struct nfs4_stateid, st_perfile); + list_for_each_entry(stq, &fp->fi_perfile, st_perfile) { if(stq->st_stateowner == sop) { stp = stq; continue; @@ -1253,6 +1261,17 @@ if (fp && list_empty(&fp->fi_perfile)) release_file(fp); + if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { + if (status) + status = nfserr_reclaim_bad; + else { + /* successful reclaim. so_seqid is decremented because + * it will be bumped in encode_open + */ + open->op_stateowner->so_confirmed = 1; + open->op_stateowner->so_seqid--; + } + } /* * To finish the open response, we just need to set the rflags. */ @@ -1260,12 +1279,12 @@ if (!open->op_stateowner->so_confirmed) open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; - nfs4_unlock_state(); return status; out_free: kfree(stp); goto out; } + static struct work_struct laundromat_work; static void laundromat_main(void *); static DECLARE_WORK(laundromat_work, laundromat_main, NULL); @@ -1274,7 +1293,6 @@ nfsd4_renew(clientid_t *clid) { struct nfs4_client *clp; - struct list_head *pos, *next; unsigned int idhashval; int status; @@ -1286,15 +1304,13 @@ goto out; status = nfs_ok; idhashval = clientid_hashval(clid->cl_id); - list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_idhash); + list_for_each_entry(clp, &conf_id_hashtbl[idhashval], cl_idhash) { if (!cmp_clid(&clp->cl_clientid, clid)) continue; renew_client(clp); goto out; } - list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) { - clp = list_entry(pos, struct nfs4_client, cl_idhash); + list_for_each_entry(clp, &unconf_id_hashtbl[idhashval], cl_idhash) { if (!cmp_clid(&clp->cl_clientid, clid)) continue; renew_client(clp); @@ -1316,9 +1332,11 @@ nfs4_laundromat(void) { struct nfs4_client *clp; + struct nfs4_stateowner *sop; struct list_head *pos, *next; time_t cutoff = get_seconds() - NFSD_LEASE_TIME; - time_t t, return_val = NFSD_LEASE_TIME; + time_t t, clientid_val = NFSD_LEASE_TIME; + time_t u, close_val = NFSD_LEASE_TIME; nfs4_lock_state(); @@ -1327,18 +1345,30 @@ clp = list_entry(pos, struct nfs4_client, cl_lru); if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) { t = clp->cl_time - cutoff; - if (return_val > t) - return_val = t; + if (clientid_val > t) + clientid_val = t; break; } dprintk("NFSD: purging unused client (clientid %08x)\n", clp->cl_clientid.cl_id); expire_client(clp); } - if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT) - return_val = NFSD_LAUNDROMAT_MINTIMEOUT; + list_for_each_safe(pos, next, &close_lru) { + sop = list_entry(pos, struct nfs4_stateowner, so_close_lru); + if (time_after((unsigned long)sop->so_time, (unsigned long)cutoff)) { + u = sop->so_time - cutoff; + if (close_val > u) + close_val = u; + break; + } + dprintk("NFSD: purging unused open stateowner (so_id %d)\n", + sop->so_id); + release_stateowner(sop); + } + if (clientid_val < NFSD_LAUNDROMAT_MINTIMEOUT) + clientid_val = NFSD_LAUNDROMAT_MINTIMEOUT; nfs4_unlock_state(); - return return_val; + return clientid_val; } void @@ -1351,17 +1381,19 @@ schedule_delayed_work(&laundromat_work, t*HZ); } -/* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */ +/* search ownerid_hashtbl[] and close_lru for stateid owner + * (stateid->si_stateownerid) + */ struct nfs4_stateowner * -find_openstateowner_id(u32 st_id) { - struct list_head *pos, *next; +find_openstateowner_id(u32 st_id, int flags) { struct nfs4_stateowner *local = NULL; - unsigned int hashval = ownerid_hashval(st_id); - list_for_each_safe(pos, next, &ownerid_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateowner, so_idhash); - if(local->so_id == st_id) - return local; + dprintk("NFSD: find_openstateowner_id %d\n", st_id); + if (flags & CLOSE_STATE) { + list_for_each_entry(local, &close_lru, so_close_lru) { + if(local->so_id == st_id) + return local; + } } return NULL; } @@ -1547,11 +1579,12 @@ * starting by trying to look up the stateowner. * If stateowner is not found - stateid is bad. */ - if (!(sop = find_openstateowner_id(stateid->si_stateownerid))) { + if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) { printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n"); status = nfserr_bad_stateid; goto out; } + *sopp = sop; check_replay: if (seqid == sop->so_seqid) { @@ -1561,11 +1594,15 @@ } else { printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid); + *sopp = NULL; status = nfserr_bad_seqid; } goto out; } +/* + * nfs4_unlock_state(); called in encode + */ int nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc) { @@ -1601,7 +1638,6 @@ stp->st_stateid.si_generation); status = nfs_ok; out: - nfs4_unlock_state(); return status; } @@ -1630,6 +1666,9 @@ } } +/* + * nfs4_unlock_state(); called in encode + */ int nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od) @@ -1642,6 +1681,7 @@ (int)current_fh->fh_dentry->d_name.len, current_fh->fh_dentry->d_name.name); + od->od_stateowner = NULL; status = nfserr_inval; if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny)) goto out; @@ -1675,10 +1715,12 @@ memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); status = nfs_ok; out: - nfs4_unlock_state(); return status; } +/* + * nfs4_unlock_state() called after encode + */ int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close) { @@ -1689,10 +1731,12 @@ (int)current_fh->fh_dentry->d_name.len, current_fh->fh_dentry->d_name.name); + close->cl_stateowner = NULL; nfs4_lock_state(); + /* check close_lru for replay */ if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, &close->cl_stateid, - CHECK_FH | OPEN_STATE, + CHECK_FH | OPEN_STATE | CLOSE_STATE, &close->cl_stateowner, &stp, NULL))) goto out; /* @@ -1705,7 +1749,6 @@ /* release_state_owner() calls nfsd_close() if needed */ release_state_owner(stp, &close->cl_stateowner, OPEN_STATE); out: - nfs4_unlock_state(); return status; } @@ -1729,7 +1772,6 @@ struct nfs4_stateid * find_stateid(stateid_t *stid, int flags) { - struct list_head *pos, *next; struct nfs4_stateid *local = NULL; u32 st_id = stid->si_stateownerid; u32 f_id = stid->si_fileid; @@ -1738,8 +1780,7 @@ dprintk("NFSD: find_stateid flags 0x%x\n",flags); if ((flags & LOCK_STATE) || (flags & RDWR_STATE)) { hashval = stateid_hashval(st_id, f_id); - list_for_each_safe(pos, next, &lockstateid_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateid, st_hash); + list_for_each_entry(local, &lockstateid_hashtbl[hashval], st_hash) { if((local->st_stateid.si_stateownerid == st_id) && (local->st_stateid.si_fileid == f_id)) return local; @@ -1747,8 +1788,7 @@ } if ((flags & OPEN_STATE) || (flags & RDWR_STATE)) { hashval = stateid_hashval(st_id, f_id); - list_for_each_safe(pos, next, &stateid_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateid, st_hash); + list_for_each_entry(local, &stateid_hashtbl[hashval], st_hash) { if((local->st_stateid.si_stateownerid == st_id) && (local->st_stateid.si_fileid == f_id)) return local; @@ -1779,14 +1819,12 @@ int nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval) { - struct list_head *pos, *next; struct nfs4_stateowner *local = NULL; int status = 0; if (hashval >= LOCK_HASH_SIZE) goto out; - list_for_each_safe(pos, next, &lock_ownerid_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateowner, so_idhash); + list_for_each_entry(local, &lock_ownerid_hashtbl[hashval], so_idhash) { if (local == sop) { status = 1; goto out; @@ -1817,11 +1855,9 @@ static int find_lockstateowner_str(unsigned int hashval, struct xdr_netobj *owner, clientid_t *clid, struct nfs4_stateowner **op) { - struct list_head *pos, *next; struct nfs4_stateowner *local = NULL; - list_for_each_safe(pos, next, &lock_ownerstr_hashtbl[hashval]) { - local = list_entry(pos, struct nfs4_stateowner, so_strhash); + list_for_each_entry(local, &lock_ownerstr_hashtbl[hashval], so_strhash) { if(!cmp_owner_str(local, owner, clid)) continue; *op = local; @@ -1854,6 +1890,8 @@ INIT_LIST_HEAD(&sop->so_perclient); INIT_LIST_HEAD(&sop->so_perfilestate); INIT_LIST_HEAD(&sop->so_perlockowner); + INIT_LIST_HEAD(&sop->so_close_lru); /* not used */ + sop->so_time = 0; list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]); list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]); list_add(&sop->so_perclient, &clp->cl_perclient); @@ -1913,6 +1951,8 @@ /* * LOCK operation + * + * nfs4_unlock_state(); called in encode */ int nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock) @@ -1929,6 +1969,11 @@ (long long) lock->lk_offset, (long long) lock->lk_length); + if (nfs4_in_grace() && !lock->lk_reclaim) + return nfserr_grace; + if (nfs4_in_no_grace() && lock->lk_reclaim) + return nfserr_no_grace; + if (check_lock_length(lock->lk_offset, lock->lk_length)) return nfserr_inval; @@ -1958,8 +2003,11 @@ CHECK_FH | OPEN_STATE, &open_sop, &open_stp, &lock->v.new.clientid); - if (status) + if (status) { + if (lock->lk_reclaim) + status = nfserr_reclaim_bad; goto out; + } /* create lockowner and lock stateid */ fp = open_stp->st_file; strhashval = lock_ownerstr_hashval(fp->fi_inode, @@ -2077,7 +2125,6 @@ release_state_owner(lock_stp, &lock->lk_stateowner, LOCK_STATE); } out: - nfs4_unlock_state(); return status; } @@ -2095,6 +2142,9 @@ unsigned int strhashval; int status; + if (nfs4_in_grace()) + return nfserr_grace; + if (check_lock_length(lockt->lt_offset, lockt->lt_length)) return nfserr_inval; @@ -2188,6 +2238,7 @@ if (check_lock_length(locku->lu_offset, locku->lu_length)) return nfserr_inval; + locku->lu_stateowner = NULL; nfs4_lock_state(); if ((status = nfs4_preprocess_seqid_op(current_fh, @@ -2230,7 +2281,6 @@ memcpy(&locku->lu_stateid, &stp->st_stateid, sizeof(stateid_t)); out: - nfs4_unlock_state(); return status; out_nfserr: @@ -2265,7 +2315,6 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner) { clientid_t *clid = &rlockowner->rl_clientid; - struct list_head *pos, *next; struct nfs4_stateowner *local = NULL; struct xdr_netobj *owner = &rlockowner->rl_owner; int status, i; @@ -2286,9 +2335,7 @@ /* find the lockowner */ status = nfs_ok; for (i=0; i < LOCK_HASH_SIZE; i++) { - list_for_each_safe(pos, next, &lock_ownerstr_hashtbl[i]) { - local = list_entry(pos, struct nfs4_stateowner, - so_strhash); + list_for_each_entry(local, &lock_ownerstr_hashtbl[i], so_strhash) { if(cmp_owner_str(local, owner, clid)) break; } @@ -2299,9 +2346,7 @@ /* check for any locks held by any stateid associated with the * (lock) stateowner */ status = nfserr_locks_held; - list_for_each_safe(pos, next, &local->so_perfilestate) { - stp = list_entry(pos, struct nfs4_stateid, - st_perfilestate); + list_for_each_entry(stp, &local->so_perfilestate, st_perfilestate) { if(stp->st_vfs_set) { if (check_for_locks(&stp->st_vfs_file, local)) goto out; @@ -2324,6 +2369,7 @@ nfs4_state_init(void) { int i; + time_t start = get_seconds(); if (nfs4_init) return; @@ -2351,14 +2397,29 @@ memset(&zerostateid, 0, sizeof(stateid_t)); memset(&onestateid, ~0, sizeof(stateid_t)); + INIT_LIST_HEAD(&close_lru); INIT_LIST_HEAD(&client_lru); init_MUTEX(&client_sema); - boot_time = get_seconds(); + boot_time = start; + grace_end = start + NFSD_LEASE_TIME; INIT_WORK(&laundromat_work,laundromat_main, NULL); schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ); nfs4_init = 1; } + +int +nfs4_in_grace(void) +{ + return time_before(get_seconds(), (unsigned long)grace_end); +} + +int +nfs4_in_no_grace(void) +{ + return (grace_end < get_seconds()); +} + static void __nfs4_state_shutdown(void) diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c --- a/fs/nfsd/nfs4xdr.c Sun Apr 18 13:42:41 2004 +++ b/fs/nfsd/nfs4xdr.c Sun Apr 18 13:42:41 2004 @@ -484,11 +484,14 @@ DECODE_TAIL; } +#define NFS4_STATE_NOT_LOCKED ((void *)-1) + static int nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close) { DECODE_HEAD; + close->cl_stateowner = NFS4_STATE_NOT_LOCKED; READ_BUF(4 + sizeof(stateid_t)); READ32(close->cl_seqid); READ32(close->cl_stateid.si_generation); @@ -579,6 +582,7 @@ { DECODE_HEAD; + lock->lk_stateowner = NFS4_STATE_NOT_LOCKED; /* * type, reclaim(boolean), offset, length, new_lock_owner(boolean) */ @@ -636,6 +640,7 @@ { DECODE_HEAD; + locku->lu_stateowner = NFS4_STATE_NOT_LOCKED; READ_BUF(24 + sizeof(stateid_t)); READ32(locku->lu_type); if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT)) @@ -671,6 +676,7 @@ memset(open->op_bmval, 0, sizeof(open->op_bmval)); open->op_iattr.ia_valid = 0; + open->op_stateowner = NFS4_STATE_NOT_LOCKED; /* seqid, share_access, share_deny, clientid, ownerlen */ READ_BUF(16 + sizeof(clientid_t)); @@ -746,6 +752,7 @@ { DECODE_HEAD; + open_conf->oc_stateowner = NFS4_STATE_NOT_LOCKED; READ_BUF(4 + sizeof(stateid_t)); READ32(open_conf->oc_req_stateid.si_generation); COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t)); @@ -759,6 +766,7 @@ { DECODE_HEAD; + open_down->od_stateowner = NFS4_STATE_NOT_LOCKED; READ_BUF(4 + sizeof(stateid_t)); READ32(open_down->od_stateid.si_generation); COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t)); @@ -1259,7 +1267,8 @@ */ #define ENCODE_SEQID_OP_TAIL(stateowner) do { \ - if (seqid_mutating_err(nfserr) && stateowner) { \ + if (seqid_mutating_err(nfserr) && stateowner \ + && (stateowner != NFS4_STATE_NOT_LOCKED)) { \ if (stateowner->so_confirmed) \ stateowner->so_seqid++; \ stateowner->so_replay.rp_status = nfserr; \ @@ -1267,7 +1276,10 @@ (((char *)(resp)->p - (char *)save)); \ memcpy(stateowner->so_replay.rp_buf, save, \ stateowner->so_replay.rp_buflen); \ - } } while(0) + } \ + if (stateowner != NFS4_STATE_NOT_LOCKED) \ + nfs4_unlock_state(); \ + } while (0); static u32 nfs4_ftypes[16] = { @@ -1917,7 +1929,7 @@ ENCODE_SEQID_OP_HEAD; if (nfserr) - return; + goto out; RESERVE_SPACE(36 + sizeof(stateid_t)); WRITE32(open->op_stateid.si_generation); @@ -1972,7 +1984,7 @@ BUG(); } /* XXX save filehandle here */ - +out: ENCODE_SEQID_OP_TAIL(open->op_stateowner); } @@ -2179,6 +2191,8 @@ readdir->common.err == nfserr_toosmall && readdir->buffer == page) nfserr = nfserr_toosmall; + if (nfserr == nfserr_symlink) + nfserr = nfserr_notdir; if (nfserr) goto err_no_verf; @@ -2295,14 +2309,8 @@ RESERVE_SPACE(8); WRITE32(op->opnum); - if ((op->opnum != OP_SETATTR) && (op->opnum != OP_LOCK) && (op->opnum != OP_LOCKT) && (op->opnum != OP_SETCLIENTID) && (op->status)) { - *p++ = op->status; - ADJUST_ARGS(); - return; - } else { - statp = p++; /* to be backfilled at the end */ - ADJUST_ARGS(); - } + statp = p++; /* to be backfilled at the end */ + ADJUST_ARGS(); switch (op->opnum) { case OP_ACCESS: @@ -2406,6 +2414,8 @@ * * XDR note: do not encode rp->rp_buflen: the buffer contains the * previously sent already encoded operation. + * + * called with nfs4_lock_state() held */ void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op) @@ -2423,6 +2433,7 @@ RESERVE_SPACE(rp->rp_buflen); WRITEMEM(rp->rp_buf, rp->rp_buflen); ADJUST_ARGS(); + nfs4_unlock_state(); } /* diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c --- a/fs/ntfs/aops.c Sun Apr 18 13:42:41 2004 +++ b/fs/ntfs/aops.c Sun Apr 18 13:42:41 2004 @@ -1340,8 +1340,6 @@ void *kaddr; clear_buffer_new(bh); - if (buffer_uptodate(bh)) - buffer_error(); kaddr = kmap_atomic(page, KM_USER0); memset(kaddr + block_start, 0, bh->b_size); kunmap_atomic(kaddr, KM_USER0); diff -Nru a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c --- a/fs/openpromfs/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/openpromfs/inode.c Sun Apr 18 13:42:41 2004 @@ -1018,16 +1018,23 @@ } } +static int openprom_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NOATIME; + return 0; +} + static struct super_operations openprom_sops = { .read_inode = openprom_read_inode, .statfs = simple_statfs, + .remount_fs = openprom_remount, }; static int openprom_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; - s->s_flags |= MS_NODIRATIME; + s->s_flags |= MS_NOATIME; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = OPENPROM_SUPER_MAGIC; diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c --- a/fs/proc/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/proc/inode.c Sun Apr 18 13:42:41 2004 @@ -127,6 +127,12 @@ return 0; } +static int proc_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + static struct super_operations proc_sops = { .alloc_inode = proc_alloc_inode, .destroy_inode = proc_destroy_inode, @@ -134,6 +140,7 @@ .drop_inode = generic_delete_inode, .delete_inode = proc_delete_inode, .statfs = simple_statfs, + .remount_fs = proc_remount, }; enum { diff -Nru a/fs/qnx4/inode.c b/fs/qnx4/inode.c --- a/fs/qnx4/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/qnx4/inode.c Sun Apr 18 13:42:41 2004 @@ -149,9 +149,13 @@ qs = qnx4_sb(sb); qs->Version = QNX4_VERSION; +#ifndef CONFIG_QNX4FS_RW + *flags |= MS_RDONLY; +#endif if (*flags & MS_RDONLY) { return 0; } + mark_buffer_dirty(qs->sb_buf); return 0; diff -Nru a/fs/quota_v1.c b/fs/quota_v1.c --- a/fs/quota_v1.c Sun Apr 18 13:42:41 2004 +++ b/fs/quota_v1.c Sun Apr 18 13:42:41 2004 @@ -60,7 +60,7 @@ v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 && dquot->dq_dqb.dqb_ihardlimit == 0 && dquot->dq_dqb.dqb_isoftlimit == 0) - dquot->dq_flags |= DQ_FAKE; + set_bit(DQ_FAKE_B, &dquot->dq_flags); dqstats.reads++; return 0; @@ -80,12 +80,7 @@ fs = get_fs(); set_fs(KERNEL_DS); - /* - * Note: clear the DQ_MOD flag unconditionally, - * so we don't loop forever on failure. - */ v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); - dquot->dq_flags &= ~DQ_MOD; if (dquot->dq_id == 0) { dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; diff -Nru a/fs/quota_v2.c b/fs/quota_v2.c --- a/fs/quota_v2.c Sun Apr 18 13:42:41 2004 +++ b/fs/quota_v2.c Sun Apr 18 13:42:41 2004 @@ -65,7 +65,7 @@ set_fs(fs); if (size != sizeof(struct v2_disk_dqinfo)) { printk(KERN_WARNING "Can't read info structure on device %s.\n", - f->f_vfsmnt->mnt_sb->s_id); + f->f_dentry->d_sb->s_id); return -1; } info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); @@ -87,10 +87,12 @@ ssize_t size; loff_t offset = V2_DQINFOOFF; + spin_lock(&dq_data_lock); info->dqi_flags &= ~DQF_INFO_DIRTY; dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace); dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK); + spin_unlock(&dq_data_lock); dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks); dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk); dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry); @@ -100,7 +102,7 @@ set_fs(fs); if (size != sizeof(struct v2_disk_dqinfo)) { printk(KERN_WARNING "Can't write info structure on device %s.\n", - f->f_vfsmnt->mnt_sb->s_id); + f->f_dentry->d_sb->s_id); return -1; } return 0; @@ -173,9 +175,10 @@ } /* Remove empty block from list and return it */ -static int get_free_dqblk(struct file *filp, struct mem_dqinfo *info) +static int get_free_dqblk(struct file *filp, int type) { dqbuf_t buf = getdqbuf(); + struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int ret, blk; @@ -193,7 +196,7 @@ goto out_buf; blk = info->u.v2_i.dqi_blocks++; } - mark_info_dirty(info); + mark_info_dirty(filp->f_dentry->d_sb, type); ret = blk; out_buf: freedqbuf(buf); @@ -201,8 +204,9 @@ } /* Insert empty block to the list */ -static int put_free_dqblk(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +static int put_free_dqblk(struct file *filp, int type, dqbuf_t buf, uint blk) { + struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int err; @@ -210,16 +214,17 @@ dh->dqdh_prev_free = cpu_to_le32(0); dh->dqdh_entries = cpu_to_le16(0); info->u.v2_i.dqi_free_blk = blk; - mark_info_dirty(info); + mark_info_dirty(filp->f_dentry->d_sb, type); if ((err = write_blk(filp, blk, buf)) < 0) /* Some strange block. We had better leave it... */ return err; return 0; } /* Remove given block from the list of blocks with free entries */ -static int remove_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +static int remove_free_dqentry(struct file *filp, int type, dqbuf_t buf, uint blk) { dqbuf_t tmpbuf = getdqbuf(); + struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free); int err; @@ -242,7 +247,7 @@ } else { info->u.v2_i.dqi_free_entry = nextblk; - mark_info_dirty(info); + mark_info_dirty(filp->f_dentry->d_sb, type); } freedqbuf(tmpbuf); dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); @@ -255,9 +260,10 @@ } /* Insert given block to the beginning of list with free entries */ -static int insert_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk) +static int insert_free_dqentry(struct file *filp, int type, dqbuf_t buf, uint blk) { dqbuf_t tmpbuf = getdqbuf(); + struct mem_dqinfo *info = sb_dqinfo(filp->f_dentry->d_sb, type); struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf; int err; @@ -276,7 +282,7 @@ } freedqbuf(tmpbuf); info->u.v2_i.dqi_free_entry = blk; - mark_info_dirty(info); + mark_info_dirty(filp->f_dentry->d_sb, type); return 0; out_buf: freedqbuf(tmpbuf); @@ -307,7 +313,7 @@ goto out_buf; } else { - blk = get_free_dqblk(filp, info); + blk = get_free_dqblk(filp, dquot->dq_type); if ((int)blk < 0) { *err = blk; freedqbuf(buf); @@ -315,10 +321,10 @@ } memset(buf, 0, V2_DQBLKSIZE); info->u.v2_i.dqi_free_entry = blk; /* This is enough as block is already zeroed and entry list is empty... */ - mark_info_dirty(info); + mark_info_dirty(dquot->dq_sb, dquot->dq_type); } if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK) /* Block will be full? */ - if ((*err = remove_free_dqentry(filp, info, buf, blk)) < 0) { + if ((*err = remove_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0) { printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk); goto out_buf; } @@ -349,7 +355,6 @@ static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth) { struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; - struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; dqbuf_t buf; int ret = 0, newson = 0, newact = 0; u32 *ref; @@ -358,7 +363,7 @@ if (!(buf = getdqbuf())) return -ENOMEM; if (!*treeblk) { - ret = get_free_dqblk(filp, info); + ret = get_free_dqblk(filp, dquot->dq_type); if (ret < 0) goto out_buf; *treeblk = ret; @@ -392,7 +397,7 @@ ret = write_blk(filp, *treeblk, buf); } else if (newact && ret < 0) - put_free_dqblk(filp, info, buf, *treeblk); + put_free_dqblk(filp, dquot->dq_type, buf, *treeblk); out_buf: freedqbuf(buf); return ret; @@ -417,6 +422,7 @@ ssize_t ret; struct v2_disk_dqblk ddquot; + /* dq_off is guarded by dqio_sem */ if (!dquot->dq_off) if ((ret = dq_insert_tree(dquot)) < 0) { printk(KERN_ERR "VFS: Error %Zd occurred while creating quota.\n", ret); @@ -424,7 +430,9 @@ } filp = sb_dqopt(dquot->dq_sb)->files[type]; offset = dquot->dq_off; + spin_lock(&dq_data_lock); mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id); + spin_unlock(&dq_data_lock); fs = get_fs(); set_fs(KERNEL_DS); ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct v2_disk_dqblk), &offset); @@ -445,7 +453,6 @@ static int free_dqentry(struct dquot *dquot, uint blk) { struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; - struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; struct v2_disk_dqdbheader *dh; dqbuf_t buf = getdqbuf(); int ret = 0; @@ -463,8 +470,8 @@ dh = (struct v2_disk_dqdbheader *)buf; dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1); if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ - if ((ret = remove_free_dqentry(filp, info, buf, blk)) < 0 || - (ret = put_free_dqblk(filp, info, buf, blk)) < 0) { + if ((ret = remove_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0 || + (ret = put_free_dqblk(filp, dquot->dq_type, buf, blk)) < 0) { printk(KERN_ERR "VFS: Can't move quota data block (%u) to free list.\n", blk); goto out_buf; } @@ -473,7 +480,7 @@ memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0, sizeof(struct v2_disk_dqblk)); if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) { /* Insert will write block itself */ - if ((ret = insert_free_dqentry(filp, info, buf, blk)) < 0) { + if ((ret = insert_free_dqentry(filp, dquot->dq_type, buf, blk)) < 0) { printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk); goto out_buf; } @@ -494,7 +501,6 @@ static int remove_tree(struct dquot *dquot, uint *blk, int depth) { struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; - struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type; dqbuf_t buf = getdqbuf(); int ret = 0; uint newblk; @@ -518,7 +524,7 @@ ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0); for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++); /* Block got empty? */ if (i == V2_DQBLKSIZE) { - put_free_dqblk(filp, info, buf, *blk); + put_free_dqblk(filp, dquot->dq_type, buf, *blk); *blk = 0; } else @@ -632,7 +638,7 @@ if (offset < 0) printk(KERN_ERR "VFS: Can't read quota structure for id %u.\n", dquot->dq_id); dquot->dq_off = 0; - dquot->dq_flags |= DQ_FAKE; + set_bit(DQ_FAKE_B, &dquot->dq_flags); memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); ret = offset; } @@ -650,21 +656,24 @@ ret = 0; set_fs(fs); disk2memdqb(&dquot->dq_dqb, &ddquot); + if (!dquot->dq_dqb.dqb_bhardlimit && + !dquot->dq_dqb.dqb_bsoftlimit && + !dquot->dq_dqb.dqb_ihardlimit && + !dquot->dq_dqb.dqb_isoftlimit) + set_bit(DQ_FAKE_B, &dquot->dq_flags); } dqstats.reads++; return ret; } -/* Commit changes of dquot to disk - it might also mean deleting it when quota became fake one and user has no blocks... */ -static int v2_commit_dquot(struct dquot *dquot) +/* Check whether dquot should not be deleted. We know we are + * the only one operating on dquot (thanks to dq_lock) */ +static int v2_release_dquot(struct dquot *dquot) { - /* We clear the flag everytime so we don't loop when there was an IO error... */ - dquot->dq_flags &= ~DQ_MOD; - if (dquot->dq_flags & DQ_FAKE && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) + if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) return v2_delete_dquot(dquot); - else - return v2_write_dquot(dquot); + return 0; } static struct quota_format_ops v2_format_ops = { @@ -673,7 +682,8 @@ .write_file_info = v2_write_file_info, .free_file_info = NULL, .read_dqblk = v2_read_dquot, - .commit_dqblk = v2_commit_dquot, + .commit_dqblk = v2_write_dquot, + .release_dqblk = v2_release_dquot, }; static struct quota_format_type v2_quota_format = { diff -Nru a/fs/read_write.c b/fs/read_write.c --- a/fs/read_write.c Sun Apr 18 13:42:41 2004 +++ b/fs/read_write.c Sun Apr 18 13:42:41 2004 @@ -635,7 +635,7 @@ return ret; } - return do_sendfile(out_fd, in_fd, NULL, count, MAX_NON_LFS); + return do_sendfile(out_fd, in_fd, NULL, count, 0); } asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c --- a/fs/reiserfs/inode.c Sun Apr 18 13:42:40 2004 +++ b/fs/reiserfs/inode.c Sun Apr 18 13:42:40 2004 @@ -1925,7 +1925,6 @@ th.t_trans_id = 0; if (!buffer_uptodate(bh_result)) { - buffer_error(); return -EIO; } @@ -2057,8 +2056,6 @@ * in the BH_Uptodate is just a sanity check. */ if (!page_has_buffers(page)) { - if (!PageUptodate(page)) - buffer_error(); create_empty_buffers(page, inode->i_sb->s_blocksize, (1 << BH_Dirty) | (1 << BH_Uptodate)); } @@ -2120,8 +2117,6 @@ } } if (test_clear_buffer_dirty(bh)) { - if (!buffer_uptodate(bh)) - buffer_error(); mark_buffer_async_write(bh); } else { unlock_buffer(bh); diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c --- a/fs/reiserfs/journal.c Sun Apr 18 13:42:41 2004 +++ b/fs/reiserfs/journal.c Sun Apr 18 13:42:41 2004 @@ -86,6 +86,7 @@ /* journal list state bits */ #define LIST_TOUCHED 1 #define LIST_DIRTY 2 +#define LIST_COMMIT_PENDING 4 /* someone will commit this list */ /* flags for do_journal_end */ #define FLUSH_ALL 1 /* flush commit and real blocks */ @@ -2308,6 +2309,7 @@ SB_JOURNAL_MAX_TRANS_AGE(p_s_sb) = commit_max_age; } else { SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb) = le32_to_cpu (jh->jh_journal.jp_journal_max_commit_age); + SB_JOURNAL_DEFAULT_MAX_COMMIT_AGE(p_s_sb) = SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb); SB_JOURNAL_MAX_TRANS_AGE(p_s_sb) = JOURNAL_MAX_TRANS_AGE; } @@ -2462,8 +2464,20 @@ } static void queue_log_writer(struct super_block *s) { + wait_queue_t wait; set_bit(WRITERS_QUEUED, &SB_JOURNAL(s)->j_state); - sleep_on(&SB_JOURNAL(s)->j_join_wait); + + /* + * we don't want to use wait_event here because + * we only want to wait once. + */ + init_waitqueue_entry(&wait, current); + add_wait_queue(&SB_JOURNAL(s)->j_join_wait, &wait); + set_current_state(TASK_UNINTERRUPTIBLE); + if (test_bit(WRITERS_QUEUED, &SB_JOURNAL(s)->j_state)) + schedule(); + current->state = TASK_RUNNING; + remove_wait_queue(&SB_JOURNAL(s)->j_join_wait, &wait); } static void wake_queued_writers(struct super_block *s) { @@ -2476,7 +2490,9 @@ { unsigned long bcount = SB_JOURNAL(sb)->j_bcount; while(1) { - yield(); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + SB_JOURNAL(sb)->j_current_jl->j_state |= LIST_COMMIT_PENDING; while ((atomic_read(&SB_JOURNAL(sb)->j_wcount) > 0 || atomic_read(&SB_JOURNAL(sb)->j_jlock)) && SB_JOURNAL(sb)->j_trans_id == trans_id) { @@ -2909,9 +2925,15 @@ flush_commit_list(p_s_sb, jl, 1); } unlock_kernel(); - atomic_inc(&SB_JOURNAL(p_s_sb)->j_async_throttle); - filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping); - atomic_dec(&SB_JOURNAL(p_s_sb)->j_async_throttle); + /* + * this is a little racey, but there's no harm in missing + * the filemap_fdata_write + */ + if (!atomic_read(&SB_JOURNAL(p_s_sb)->j_async_throttle)) { + atomic_inc(&SB_JOURNAL(p_s_sb)->j_async_throttle); + filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping); + atomic_dec(&SB_JOURNAL(p_s_sb)->j_async_throttle); + } } /* @@ -3000,7 +3022,8 @@ jl = SB_JOURNAL(p_s_sb)->j_current_jl; trans_id = jl->j_trans_id; - + if (wait_on_commit) + jl->j_state |= LIST_COMMIT_PENDING; atomic_set(&(SB_JOURNAL(p_s_sb)->j_jlock), 1) ; if (flush) { SB_JOURNAL(p_s_sb)->j_next_full_flush = 1 ; @@ -3522,8 +3545,8 @@ if (flush) { flush_commit_list(p_s_sb, jl, 1) ; flush_journal_list(p_s_sb, jl, 1) ; - } else - queue_work(commit_wq, &SB_JOURNAL(p_s_sb)->j_work); + } else if (!(jl->j_state & LIST_COMMIT_PENDING)) + queue_delayed_work(commit_wq, &SB_JOURNAL(p_s_sb)->j_work, HZ/10); /* if the next transaction has any chance of wrapping, flush diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c --- a/fs/reiserfs/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/reiserfs/super.c Sun Apr 18 13:42:41 2004 @@ -709,13 +709,11 @@ char *p = 0; int val = simple_strtoul (arg, &p, 0); /* commit=NNN (time in seconds) */ - if ( *p != '\0' || val == 0) { + if ( *p != '\0' || val < 0) { printk ("reiserfs_parse_options: bad value %s\n", arg); return 0; } - if ( val > 0 ) { - *commit_max_age = val; - } + *commit_max_age = val; } if ( c == 'w' ) { @@ -821,8 +819,14 @@ REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)->s_mount_opt & ~safe_mask) | (mount_options & safe_mask); if(commit_max_age != 0) { - SB_JOURNAL_MAX_COMMIT_AGE(s) = commit_max_age; - SB_JOURNAL_MAX_TRANS_AGE(s) = commit_max_age; + SB_JOURNAL_MAX_COMMIT_AGE(s) = commit_max_age; + SB_JOURNAL_MAX_TRANS_AGE(s) = commit_max_age; + } + else + { + /* 0 means restore defaults. */ + SB_JOURNAL_MAX_COMMIT_AGE(s) = SB_JOURNAL_DEFAULT_MAX_COMMIT_AGE(s); + SB_JOURNAL_MAX_TRANS_AGE(s) = JOURNAL_MAX_TRANS_AGE; } if(blocks) { diff -Nru a/fs/romfs/inode.c b/fs/romfs/inode.c --- a/fs/romfs/inode.c Sun Apr 18 13:42:41 2004 +++ b/fs/romfs/inode.c Sun Apr 18 13:42:41 2004 @@ -592,11 +592,18 @@ printk(KERN_INFO "romfs_inode_cache: not all structures were freed\n"); } +static int romfs_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_RDONLY; + return 0; +} + static struct super_operations romfs_ops = { .alloc_inode = romfs_alloc_inode, .destroy_inode = romfs_destroy_inode, .read_inode = romfs_read_inode, .statfs = romfs_statfs, + .remount_fs = romfs_remount, }; static struct super_block *romfs_get_sb(struct file_system_type *fs_type, diff -Nru a/fs/smbfs/inode.c b/fs/smbfs/inode.c --- a/fs/smbfs/inode.c Sun Apr 18 13:42:40 2004 +++ b/fs/smbfs/inode.c Sun Apr 18 13:42:40 2004 @@ -93,6 +93,12 @@ printk(KERN_INFO "smb_inode_cache: not all structures were freed\n"); } +static int smb_remount(struct super_block *sb, int *flags, char *data) +{ + *flags |= MS_NODIRATIME; + return 0; +} + static struct super_operations smb_sops = { .alloc_inode = smb_alloc_inode, @@ -102,6 +108,7 @@ .put_super = smb_put_super, .statfs = smb_statfs, .show_options = smb_show_options, + .remount_fs = smb_remount, }; diff -Nru a/fs/stat.c b/fs/stat.c --- a/fs/stat.c Sun Apr 18 13:42:40 2004 +++ b/fs/stat.c Sun Apr 18 13:42:40 2004 @@ -398,6 +398,8 @@ void inode_set_bytes(struct inode *inode, loff_t bytes) { + /* Caller is here responsible for sufficient locking + * (ie. inode->i_lock) */ inode->i_blocks = bytes >> 9; inode->i_bytes = bytes & 511; } diff -Nru a/fs/super.c b/fs/super.c --- a/fs/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/super.c Sun Apr 18 13:42:41 2004 @@ -562,7 +562,9 @@ spin_unlock(&unnamed_dev_lock); if ((dev & MAX_ID_MASK) == (1 << MINORBITS)) { + spin_lock(&unnamed_dev_lock); idr_remove(&unnamed_dev_idr, dev); + spin_unlock(&unnamed_dev_lock); return -EMFILE; } s->s_dev = MKDEV(0, dev & MINORMASK); diff -Nru a/fs/sysv/inode.c b/fs/sysv/inode.c --- a/fs/sysv/inode.c Sun Apr 18 13:42:40 2004 +++ b/fs/sysv/inode.c Sun Apr 18 13:42:40 2004 @@ -57,6 +57,16 @@ unlock_kernel(); } +static int sysv_remount(struct super_block *sb, int *flags, char *data) +{ + struct sysv_sb_info *sbi = SYSV_SB(sb); + if (sbi->s_forced_ro) + *flags |= MS_RDONLY; + if (!(*flags & MS_RDONLY)) + sb->s_dirt = 1; + return 0; +} + static void sysv_put_super(struct super_block *sb) { struct sysv_sb_info *sbi = SYSV_SB(sb); @@ -321,6 +331,7 @@ .delete_inode = sysv_delete_inode, .put_super = sysv_put_super, .write_super = sysv_write_super, + .remount_fs = sysv_remount, .statfs = sysv_statfs, }; diff -Nru a/fs/sysv/super.c b/fs/sysv/super.c --- a/fs/sysv/super.c Sun Apr 18 13:42:40 2004 +++ b/fs/sysv/super.c Sun Apr 18 13:42:40 2004 @@ -206,11 +206,11 @@ if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) { sbi->s_type = FSTYPE_AFS; + sbi->s_forced_ro = 1; if (!(sb->s_flags & MS_RDONLY)) { printk("SysV FS: SCO EAFS on %s detected, " "forcing read-only mode.\n", sb->s_id); - sb->s_flags |= MS_RDONLY; } return sbd->s_type; } @@ -234,7 +234,7 @@ if (sbd->s_type >= 0x10) { printk("SysV FS: can't handle long file names on %s, " "forcing read-only mode.\n", sb->s_id); - sb->s_flags |= MS_RDONLY; + sbi->s_forced_ro = 1; } sbi->s_type = FSTYPE_SYSV4; @@ -335,9 +335,10 @@ printk("SysV FS: get root dentry failed\n"); return 0; } + if (sbi->s_forced_ro) + sb->s_flags |= MS_RDONLY; if (sbi->s_truncate) sb->s_root->d_op = &sysv_dentry_operations; - sb->s_flags |= MS_RDONLY; sb->s_dirt = 1; return 1; } @@ -481,6 +482,7 @@ (fs32_to_cpu(sbi, v7i->i_size) & 017) != 0) goto failed; brelse(bh2); + bh2 = NULL; sbi->s_bh1 = bh; sbi->s_bh2 = bh; diff -Nru a/fs/sysv/sysv.h b/fs/sysv/sysv.h --- a/fs/sysv/sysv.h Sun Apr 18 13:42:41 2004 +++ b/fs/sysv/sysv.h Sun Apr 18 13:42:41 2004 @@ -54,6 +54,7 @@ u32 s_ndatazones; /* total number of data zones */ u32 s_nzones; /* same as s_sbd->s_fsize */ u16 s_namelen; /* max length of dir entry */ + int s_forced_ro; }; /* diff -Nru a/fs/udf/super.c b/fs/udf/super.c --- a/fs/udf/super.c Sun Apr 18 13:42:41 2004 +++ b/fs/udf/super.c Sun Apr 18 13:42:41 2004 @@ -460,6 +460,12 @@ UDF_SB(sb)->s_gid = uopt.gid; UDF_SB(sb)->s_umask = uopt.umask; + if (UDF_SB_LVIDBH(sb)) { + int write_rev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev); + if (write_rev > UDF_MAX_WRITE_VERSION) + *flags |= MS_RDONLY; + } + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) diff -Nru a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h --- a/include/asm-arm/cacheflush.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-arm/cacheflush.h Sun Apr 18 13:42:41 2004 @@ -295,7 +295,9 @@ static inline void flush_dcache_page(struct page *page) { - if (page_mapping(page) && !mapping_mapped(page->mapping)) + struct address_space *mapping = page_mapping(page); + + if (mapping && !mapping_mapped(mapping)) set_bit(PG_dcache_dirty, &page->flags); else __flush_dcache_page(page); diff -Nru a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h --- a/include/asm-arm/pgtable.h Sun Apr 18 13:42:40 2004 +++ b/include/asm-arm/pgtable.h Sun Apr 18 13:42:40 2004 @@ -15,13 +15,62 @@ #include /* - * We pull a couple of tricks here: - * 1. We wrap the PMD into the PGD. - * 2. We lie about the size of the PTE and PGD. - * Even though we have 256 PTE entries and 4096 PGD entries, we tell - * Linux that we actually have 512 PTE entries and 2048 PGD entries. - * Each "Linux" PGD entry is made up of two hardware PGD entries, and - * each PTE table is actually two hardware PTE tables. + * Hardware-wise, we have a two level page table structure, where the first + * level has 4096 entries, and the second level has 256 entries. Each entry + * is one 32-bit word. Most of the bits in the second level entry are used + * by hardware, and there aren't any "accessed" and "dirty" bits. + * + * Linux on the other hand has a three level page table structure, which can + * be wrapped to fit a two level page table structure easily - using the PGD + * and PTE only. However, Linux also expects one "PTE" table per page, and + * at least a "dirty" bit. + * + * Therefore, we tweak the implementation slightly - we tell Linux that we + * have 2048 entries in the first level, each of which is 8 bytes (iow, two + * hardware pointers to the second level.) The second level contains two + * hardware PTE tables arranged contiguously, followed by Linux versions + * which contain the state information Linux needs. We, therefore, end up + * with 512 entries in the "PTE" level. + * + * This leads to the page tables having the following layout: + * + * pgd pte + * | | + * +--------+ +0 + * | |-----> +------------+ +0 + * +- - - - + +4 | h/w pt 0 | + * | |-----> +------------+ +1024 + * +--------+ +8 | h/w pt 1 | + * | | +------------+ +2048 + * +- - - - + | Linux pt 0 | + * | | +------------+ +3072 + * +--------+ | Linux pt 1 | + * | | +------------+ +4096 + * + * See L_PTE_xxx below for definitions of bits in the "Linux pt", and + * PTE_xxx for definitions of bits appearing in the "h/w pt". + * + * PMD_xxx definitions refer to bits in the first level page table. + * + * The "dirty" bit is emulated by only granting hardware write permission + * iff the page is marked "writable" and "dirty" in the Linux PTE. This + * means that a write to a clean page will cause a permission fault, and + * the Linux MM layer will mark the page dirty via handle_pte_fault(). + * For the hardware to notice the permission change, the TLB entry must + * be flushed, and ptep_establish() does that for us. + * + * The "accessed" or "young" bit is emulated by a similar method; we only + * allow accesses to the page if the "young" bit is set. Accesses to the + * page will cause a fault, and handle_pte_fault() will set the young bit + * for us as long as the page is marked present in the corresponding Linux + * PTE entry. Again, ptep_establish() will ensure that the TLB is up to + * date. + * + * However, when the "young" bit is cleared, we deny access to the page + * by clearing the hardware PTE. Currently Linux does not flush the TLB + * for us in this case, which means the TLB will retain the transation + * until either the TLB entry is evicted under pressure, or a context + * switch which changes the user space mapping occurs. */ #define PTRS_PER_PTE 512 #define PTRS_PER_PMD 1 diff -Nru a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h --- a/include/asm-arm/uaccess.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-arm/uaccess.h Sun Apr 18 13:42:41 2004 @@ -75,7 +75,7 @@ #define access_ok(type,addr,size) (__range_ok(addr,size) == 0) -static inline int verify_area(int type, const void * addr, unsigned long size) +static inline int verify_area(int type, const void __user *addr, unsigned long size) { return access_ok(type, addr, size) ? 0 : -EFAULT; } @@ -354,13 +354,13 @@ : "r" (x), "i" (-EFAULT) \ : "cc") -extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n); -extern unsigned long __arch_copy_to_user(void *to, const void *from, unsigned long n); -extern unsigned long __arch_clear_user(void *addr, unsigned long n); -extern unsigned long __arch_strncpy_from_user(char *to, const char *from, unsigned long count); -extern unsigned long __arch_strnlen_user(const char *s, long n); +extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __arch_clear_user(void __user *addr, unsigned long n); +extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count); +extern unsigned long __arch_strnlen_user(const char __user *s, long n); -static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n) +static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { if (access_ok(VERIFY_READ, from, n)) n = __arch_copy_from_user(to, from, n); @@ -369,36 +369,36 @@ return n; } -static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n) +static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { return __arch_copy_from_user(to, from, n); } -static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n) +static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) n = __arch_copy_to_user(to, from, n); return n; } -static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n) +static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) { return __arch_copy_to_user(to, from, n); } -static __inline__ unsigned long clear_user (void *to, unsigned long n) +static inline unsigned long clear_user (void __user *to, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) n = __arch_clear_user(to, n); return n; } -static __inline__ unsigned long __clear_user (void *to, unsigned long n) +static inline unsigned long __clear_user (void __user *to, unsigned long n) { return __arch_clear_user(to, n); } -static __inline__ long strncpy_from_user (char *dst, const char *src, long count) +static inline long strncpy_from_user (char *dst, const char __user *src, long count) { long res = -EFAULT; if (access_ok(VERIFY_READ, src, 1)) @@ -406,14 +406,14 @@ return res; } -static __inline__ long __strncpy_from_user (char *dst, const char *src, long count) +static inline long __strncpy_from_user (char *dst, const char __user *src, long count) { return __arch_strncpy_from_user(dst, src, count); } #define strlen_user(s) strnlen_user(s, ~0UL >> 1) -static inline long strnlen_user(const char *s, long n) +static inline long strnlen_user(const char __user *s, long n) { unsigned long res = 0; diff -Nru a/include/asm-generic/rmap.h b/include/asm-generic/rmap.h --- a/include/asm-generic/rmap.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-generic/rmap.h Sun Apr 18 13:42:41 2004 @@ -57,7 +57,8 @@ { struct page * page = kmap_atomic_to_page(ptep); unsigned long low_bits; - low_bits = ((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE; + low_bits = ((unsigned long)ptep & (PTRS_PER_PTE*sizeof(pte_t) - 1)) + * (PAGE_SIZE/sizeof(pte_t)); return page->index + low_bits; } diff -Nru a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h --- a/include/asm-mips/siginfo.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-mips/siginfo.h Sun Apr 18 13:42:41 2004 @@ -175,7 +175,7 @@ #undef SI_MESGQ #define SI_ASYNCIO -2 /* sent by AIO completion */ #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */ -#define SI_MESGQ -4 /* sent by real time mesq state change */ +#define SI_MESGQ __SI_CODE(__SI_MESGQ,-4) /* sent by real time mesq state change */ #ifdef __KERNEL__ diff -Nru a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h --- a/include/asm-parisc/cacheflush.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-parisc/cacheflush.h Sun Apr 18 13:42:41 2004 @@ -69,7 +69,9 @@ static inline void flush_dcache_page(struct page *page) { - if (page_mapping(page) && !mapping_mapped(page->mapping)) { + struct address_space *mapping = page_mapping(page); + + if (mapping && !mapping_mapped(mapping)) { set_bit(PG_dcache_dirty, &page->flags); } else { __flush_dcache_page(page); diff -Nru a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h --- a/include/asm-ppc64/pgtable.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-ppc64/pgtable.h Sun Apr 18 13:42:41 2004 @@ -313,7 +313,9 @@ { unsigned long old; - old = pte_update(ptep, _PAGE_ACCESSED | _PAGE_HPTEFLAGS); + if ((pte_val(*ptep) & (_PAGE_ACCESSED | _PAGE_HASHPTE)) == 0) + return 0; + old = pte_update(ptep, _PAGE_ACCESSED); if (old & _PAGE_HASHPTE) { hpte_update(ptep, old, 0); flush_tlb_pending(); /* XXX generic code doesn't flush */ @@ -326,12 +328,13 @@ * moment we always flush but we need to fix hpte_update and test if the * optimisation is worth it. */ -#if 1 static inline int ptep_test_and_clear_dirty(pte_t *ptep) { unsigned long old; - old = pte_update(ptep, _PAGE_DIRTY | _PAGE_HPTEFLAGS); + if ((pte_val(*ptep) & _PAGE_DIRTY) == 0) + return 0; + old = pte_update(ptep, _PAGE_DIRTY); if (old & _PAGE_HASHPTE) hpte_update(ptep, old, 0); return (old & _PAGE_DIRTY) != 0; @@ -341,7 +344,9 @@ { unsigned long old; - old = pte_update(ptep, _PAGE_RW | _PAGE_HPTEFLAGS); + if ((pte_val(*ptep) & _PAGE_RW) == 0) + return; + old = pte_update(ptep, _PAGE_RW); if (old & _PAGE_HASHPTE) hpte_update(ptep, old, 0); } @@ -358,7 +363,6 @@ #define ptep_clear_flush_young(__vma, __address, __ptep) \ ({ \ int __young = ptep_test_and_clear_young(__ptep); \ - flush_tlb_page(__vma, __address); \ __young; \ }) @@ -369,27 +373,6 @@ flush_tlb_page(__vma, __address); \ __dirty; \ }) - -#else -static inline int ptep_test_and_clear_dirty(pte_t *ptep) -{ - unsigned long old; - - old = pte_update(ptep, _PAGE_DIRTY); - if ((~old & (_PAGE_HASHPTE | _PAGE_RW | _PAGE_DIRTY)) == 0) - hpte_update(ptep, old, 1); - return (old & _PAGE_DIRTY) != 0; -} - -static inline void ptep_set_wrprotect(pte_t *ptep) -{ - unsigned long old; - - old = pte_update(ptep, _PAGE_RW); - if ((~old & (_PAGE_HASHPTE | _PAGE_RW | _PAGE_DIRTY)) == 0) - hpte_update(ptep, old, 1); -} -#endif static inline pte_t ptep_get_and_clear(pte_t *ptep) { diff -Nru a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h --- a/include/asm-s390/thread_info.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-s390/thread_info.h Sun Apr 18 13:42:41 2004 @@ -84,6 +84,7 @@ #define TIF_SIGPENDING 2 /* signal pending */ #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_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 */ @@ -94,6 +95,7 @@ #define _TIF_SIGPENDING (1<mapping)) + struct page *page = pfn_to_page(pfn); + struct address_space *mapping = page_mapping(page); + if (!mapping || !mapping_writably_mapped(mapping)) __clear_bit(PG_mapped, &page->flags); } } diff -Nru a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h --- a/include/asm-x86_64/ia32_unistd.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-x86_64/ia32_unistd.h Sun Apr 18 13:42:41 2004 @@ -278,7 +278,17 @@ #define __NR_ia32_tgkill 270 #define __NR_ia32_utimes 271 #define __NR_ia32_fadvise64_64 272 +#define __NR_ia32_vserver 273 +#define __NR_ia32_mbind 274 +#define __NR_ia32_get_mempolicy 275 +#define __NR_ia32_set_mempolicy 276 +#define __NR_ia32_mq_open 277 +#define __NR_ia32_mq_unlink (__NR_ia32_mq_open+1) +#define __NR_ia32_mq_timedsend (__NR_ia32_mq_open+2) +#define __NR_ia32_mq_timedreceive (__NR_ia32_mq_open+3) +#define __NR_ia32_mq_notify (__NR_ia32_mq_open+4) +#define __NR_ia32_mq_getsetattr (__NR_ia32_mq_open+5) -#define IA32_NR_syscalls 275 /* must be > than biggest syscall! */ +#define IA32_NR_syscalls 285 /* must be > than biggest syscall! */ #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h --- a/include/asm-x86_64/unistd.h Sun Apr 18 13:42:41 2004 +++ b/include/asm-x86_64/unistd.h Sun Apr 18 13:42:41 2004 @@ -532,10 +532,28 @@ __SYSCALL(__NR_utimes, sys_utimes) #define __NR_vserver 236 __SYSCALL(__NR_vserver, sys_ni_syscall) +#define __NR_vserver 236 +__SYSCALL(__NR_vserver, sys_ni_syscall) +#define __NR_mbind 237 +__SYSCALL(__NR_mbind, sys_ni_syscall) +#define __NR_set_mempolicy 238 +__SYSCALL(__NR_set_mempolicy, sys_ni_syscall) +#define __NR_get_mempolicy 239 +__SYSCALL(__NR_get_mempolicy, sys_ni_syscall) +#define __NR_mq_open 240 +__SYSCALL(__NR_mq_open, sys_mq_open) +#define __NR_mq_unlink 241 +__SYSCALL(__NR_mq_unlink, sys_mq_unlink) +#define __NR_mq_timedsend 242 +__SYSCALL(__NR_mq_timedsend, sys_mq_timedsend) +#define __NR_mq_timedreceive 243 +__SYSCALL(__NR_mq_timedreceive, sys_mq_timedreceive) +#define __NR_mq_notify 244 +__SYSCALL(__NR_mq_notify, sys_mq_notify) +#define __NR_mq_getsetattr 245 +__SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr) -/* 237,238,239 reserved for NUMA API */ - -#define __NR_syscall_max __NR_vserver +#define __NR_syscall_max __NR_mq_getsetattr #ifndef __NO_STUBS /* user-visible error numbers are in the range -1 - -4095 */ diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h --- a/include/linux/atmdev.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/atmdev.h Sun Apr 18 13:42:41 2004 @@ -399,9 +399,9 @@ * */ -static inline int atm_guess_pdu2truesize(int pdu_size) +static inline int atm_guess_pdu2truesize(int size) { - return ((pdu_size+15) & ~15) + sizeof(struct sk_buff); + return (SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info)); } diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h --- a/include/linux/buffer_head.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/buffer_head.h Sun Apr 18 13:42:40 2004 @@ -62,13 +62,6 @@ }; /* - * Debug - */ - -void __buffer_error(char *file, int line); -#define buffer_error() __buffer_error(__FILE__, __LINE__) - -/* * macro tricks to expand the set_buffer_foo(), clear_buffer_foo() * and buffer_foo() functions. */ @@ -177,7 +170,7 @@ void FASTCALL(unlock_buffer(struct buffer_head *bh)); void ll_rw_block(int, int, struct buffer_head * bh[]); void sync_dirty_buffer(struct buffer_head *bh); -int submit_bh(int, struct buffer_head *); +void submit_bh(int, struct buffer_head *); void write_boundary_block(struct block_device *bdev, sector_t bblock, unsigned blocksize); diff -Nru a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h --- a/include/linux/compat_ioctl.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/compat_ioctl.h Sun Apr 18 13:42:41 2004 @@ -123,6 +123,19 @@ COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) /* DM */ +COMPATIBLE_IOCTL(DM_VERSION_32) +COMPATIBLE_IOCTL(DM_LIST_DEVICES_32) +COMPATIBLE_IOCTL(DM_DEV_CREATE_32) +COMPATIBLE_IOCTL(DM_DEV_REMOVE_32) +COMPATIBLE_IOCTL(DM_DEV_RENAME_32) +COMPATIBLE_IOCTL(DM_DEV_SUSPEND_32) +COMPATIBLE_IOCTL(DM_DEV_STATUS_32) +COMPATIBLE_IOCTL(DM_DEV_WAIT_32) +COMPATIBLE_IOCTL(DM_TABLE_LOAD_32) +COMPATIBLE_IOCTL(DM_TABLE_CLEAR_32) +COMPATIBLE_IOCTL(DM_TABLE_DEPS_32) +COMPATIBLE_IOCTL(DM_TABLE_STATUS_32) +COMPATIBLE_IOCTL(DM_LIST_VERSIONS_32) COMPATIBLE_IOCTL(DM_VERSION) COMPATIBLE_IOCTL(DM_LIST_DEVICES) COMPATIBLE_IOCTL(DM_DEV_CREATE) diff -Nru a/include/linux/compiler.h b/include/linux/compiler.h --- a/include/linux/compiler.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/compiler.h Sun Apr 18 13:42:41 2004 @@ -4,9 +4,11 @@ #ifdef __CHECKER__ # define __user __attribute__((noderef, address_space(1))) # define __kernel /* default address space */ +# define __safe __attribute__((safe)) #else # define __user # define __kernel +# define __safe #endif #ifdef __KERNEL__ diff -Nru a/include/linux/divert.h b/include/linux/divert.h --- a/include/linux/divert.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/divert.h Sun Apr 18 13:42:41 2004 @@ -46,7 +46,7 @@ u32 uint32; s64 int64; u64 uint64; - void *ptr; + void __user *ptr; } divert_cf_arg; @@ -111,7 +111,7 @@ #ifdef CONFIG_NET_DIVERT int alloc_divert_blk(struct net_device *); void free_divert_blk(struct net_device *); -int divert_ioctl(unsigned int cmd, struct divert_cf *arg); +int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg); void divert_frame(struct sk_buff *skb); static inline void handle_diverter(struct sk_buff *skb) { diff -Nru a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h --- a/include/linux/dm-ioctl.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/dm-ioctl.h Sun Apr 18 13:42:40 2004 @@ -129,8 +129,14 @@ int32_t status; /* used when reading from kernel only */ /* - * Offset in bytes (from the start of this struct) to - * next target_spec. + * Location of the next dm_target_spec. + * - When specifying targets on a DM_TABLE_LOAD command, this value is + * the number of bytes from the start of the "current" dm_target_spec + * to the start of the "next" dm_target_spec. + * - When retrieving targets on a DM_TABLE_STATUS command, this value + * is the number of bytes from the start of the first dm_target_spec + * (that follows the dm_ioctl struct) to the start of the "next" + * dm_target_spec. */ uint32_t next; @@ -199,6 +205,34 @@ /* Added later */ DM_LIST_VERSIONS_CMD, }; + +/* + * The dm_ioctl struct passed into the ioctl is just the header + * on a larger chunk of memory. On x86-64 and other + * architectures the dm-ioctl struct will be padded to an 8 byte + * boundary so the size will be different, which would change the + * ioctl code - yes I really messed up. This hack forces these + * architectures to have the correct ioctl code. + */ +#ifdef CONFIG_COMPAT +typedef char ioctl_struct[308]; +#define DM_VERSION_32 _IOWR(DM_IOCTL, DM_VERSION_CMD, ioctl_struct) +#define DM_REMOVE_ALL_32 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, ioctl_struct) +#define DM_LIST_DEVICES_32 _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, ioctl_struct) + +#define DM_DEV_CREATE_32 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, ioctl_struct) +#define DM_DEV_REMOVE_32 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, ioctl_struct) +#define DM_DEV_RENAME_32 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, ioctl_struct) +#define DM_DEV_SUSPEND_32 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, ioctl_struct) +#define DM_DEV_STATUS_32 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, ioctl_struct) +#define DM_DEV_WAIT_32 _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, ioctl_struct) + +#define DM_TABLE_LOAD_32 _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, ioctl_struct) +#define DM_TABLE_CLEAR_32 _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, ioctl_struct) +#define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct) +#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) +#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) +#endif #define DM_IOCTL 0xfd diff -Nru a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h --- a/include/linux/dma-mapping.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/dma-mapping.h Sun Apr 18 13:42:41 2004 @@ -10,6 +10,9 @@ DMA_NONE = 3, }; +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#define DMA_32BIT_MASK 0x00000000ffffffffULL + #include /* Backwards compat, remove in 2.7.x */ diff -Nru a/include/linux/etherdevice.h b/include/linux/etherdevice.h --- a/include/linux/etherdevice.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/etherdevice.h Sun Apr 18 13:42:41 2004 @@ -25,6 +25,7 @@ #define _LINUX_ETHERDEVICE_H #include +#include #ifdef __KERNEL__ extern int eth_header(struct sk_buff *skb, struct net_device *dev, @@ -40,7 +41,9 @@ unsigned char *haddr); extern struct net_device *alloc_etherdev(int sizeof_priv); -static inline void eth_copy_and_sum (struct sk_buff *dest, unsigned char *src, int len, int base) +static inline void eth_copy_and_sum (struct sk_buff *dest, + const unsigned char *src, + int len, int base) { memcpy (dest->data, src, len); } @@ -55,13 +58,26 @@ * * Return true if the address is valid. */ -static inline int is_valid_ether_addr( u8 *addr ) +static inline int is_valid_ether_addr( const u8 *addr ) { const char zaddr[6] = {0,}; return !(addr[0]&1) && memcmp( addr, zaddr, 6); } +/** + * random_ether_addr - Generate software assigned random Ethernet address + * @addr: Pointer to a six-byte array containing the Ethernet address + * + * Generate a random Ethernet address (MAC) that is not multicast + * and has the local assigned bit set. + */ +static inline void random_ether_addr(u8 *addr) +{ + get_random_bytes (addr, ETH_ALEN); + addr [0] &= 0xfe; /* clear multicast bit */ + addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ +} #endif #endif /* _LINUX_ETHERDEVICE_H */ diff -Nru a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h --- a/include/linux/ext3_fs_sb.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/ext3_fs_sb.h Sun Apr 18 13:42:41 2004 @@ -69,6 +69,10 @@ struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ #endif +#ifdef CONFIG_QUOTA + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ + int s_jquota_fmt; /* Format of quota to use */ +#endif }; #endif /* _LINUX_EXT3_FS_SB */ diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h --- a/include/linux/ext3_jbd.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/ext3_jbd.h Sun Apr 18 13:42:40 2004 @@ -42,8 +42,9 @@ * superblock only gets updated once, of course, so don't bother * counting that again for the quota updates. */ -#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ - EXT3_XATTR_TRANS_BLOCKS - 2) +#define EXT3_DATA_TRANS_BLOCKS (EXT3_SINGLEDATA_TRANS_BLOCKS + \ + EXT3_XATTR_TRANS_BLOCKS - 2 + \ + 2*EXT3_QUOTA_TRANS_BLOCKS) extern int ext3_writepage_trans_blocks(struct inode *inode); @@ -71,6 +72,19 @@ #define EXT3_RESERVE_TRANS_BLOCKS 12U #define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 + +#ifdef CONFIG_QUOTA +/* Amount of blocks needed for quota update - we know that the structure was + * allocated so we need to update only inode+data */ +#define EXT3_QUOTA_TRANS_BLOCKS 2 +/* Amount of blocks needed for quota insert/delete - we do some block writes + * but inode, sb and group updates are done only once */ +#define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3) +#else +#define EXT3_QUOTA_TRANS_BLOCKS 0 +#define EXT3_QUOTA_INIT_BLOCKS 0 +#endif int ext3_mark_iloc_dirty(handle_t *handle, diff -Nru a/include/linux/fs.h b/include/linux/fs.h --- a/include/linux/fs.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/fs.h Sun Apr 18 13:42:40 2004 @@ -365,7 +365,7 @@ }; /* - * Radix-tre tags, for tagging dirty and writeback pages within the pagecache + * Radix-tree tags, for tagging dirty and writeback pages within the pagecache * radix trees */ #define PAGECACHE_TAG_DIRTY 0 @@ -751,7 +751,6 @@ char s_id[32]; /* Informational name */ - struct kobject kobj; /* anchor for sysfs */ void *s_fs_info; /* Filesystem private info */ /* @@ -1359,7 +1358,7 @@ extern void file_move(struct file *f, struct list_head *list); extern void file_kill(struct file *f); struct bio; -extern int submit_bio(int, struct bio *); +extern void submit_bio(int, struct bio *); extern int bdev_read_only(struct block_device *); extern int set_blocksize(struct block_device *, int); extern int sb_set_blocksize(struct super_block *, int); diff -Nru a/include/linux/icmpv6.h b/include/linux/icmpv6.h --- a/include/linux/icmpv6.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/icmpv6.h Sun Apr 18 13:42:40 2004 @@ -95,8 +95,7 @@ #define MLD2_ALLOW_NEW_SOURCES 5 #define MLD2_BLOCK_OLD_SOURCES 6 -/* this must be an IANA-assigned value; 206 for testing only */ -#define ICMPV6_MLD2_REPORT 206 +#define ICMPV6_MLD2_REPORT 143 #define MLD2_ALL_MCR_INIT { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x16 } } } /* diff -Nru a/include/linux/if.h b/include/linux/if.h --- a/include/linux/if.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/if.h Sun Apr 18 13:42:41 2004 @@ -144,7 +144,7 @@ struct ifmap ifru_map; char ifru_slave[IFNAMSIZ]; /* Just fits the size */ char ifru_newname[IFNAMSIZ]; - char * ifru_data; + char __user * ifru_data; struct if_settings ifru_settings; } ifr_ifru; }; diff -Nru a/include/linux/if_bridge.h b/include/linux/if_bridge.h --- a/include/linux/if_bridge.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/if_bridge.h Sun Apr 18 13:42:41 2004 @@ -98,9 +98,6 @@ #include -struct net_bridge; -struct net_bridge_port; - extern void brioctl_set(int (*ioctl_hook)(unsigned long)); extern int (*br_handle_frame_hook)(struct sk_buff *skb); extern int (*br_should_route_hook)(struct sk_buff **pskb); diff -Nru a/include/linux/mm.h b/include/linux/mm.h --- a/include/linux/mm.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/mm.h Sun Apr 18 13:42:40 2004 @@ -439,22 +439,27 @@ void shmem_lock(struct file * file, int lock); int shmem_zero_setup(struct vm_area_struct *); +struct zap_details; void zap_page_range(struct vm_area_struct *vma, unsigned long address, - unsigned long size); + unsigned long size, struct zap_details *); int unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm, struct vm_area_struct *start_vma, unsigned long start_addr, - unsigned long end_addr, unsigned long *nr_accounted); -void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma, - unsigned long address, unsigned long size); + unsigned long end_addr, unsigned long *nr_accounted, + struct zap_details *); void clear_page_tables(struct mmu_gather *tlb, unsigned long first, int nr); int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma); int zeromap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long size, pgprot_t prot); +void unmap_mapping_range(struct address_space *mapping, + loff_t const holebegin, loff_t const holelen, int even_cows); + +static inline void unmap_shared_mapping_range(struct address_space *mapping, + loff_t const holebegin, loff_t const holelen) +{ + unmap_mapping_range(mapping, holebegin, holelen, 0); +} -extern void invalidate_mmap_range(struct address_space *mapping, - loff_t const holebegin, - loff_t const holelen); extern int vmtruncate(struct inode * inode, loff_t offset); extern pmd_t *FASTCALL(__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)); extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); @@ -526,9 +531,8 @@ extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void __vma_link_rb(struct mm_struct *, struct vm_area_struct *, struct rb_node **, struct rb_node *); -extern struct vm_area_struct *copy_vma(struct vm_area_struct *, +extern struct vm_area_struct *copy_vma(struct vm_area_struct **, unsigned long addr, unsigned long len, unsigned long pgoff); -extern void vma_relink_file(struct vm_area_struct *, struct vm_area_struct *); extern void exit_mmap(struct mm_struct *); extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netdevice.h Sun Apr 18 13:42:41 2004 @@ -42,13 +42,14 @@ struct vlan_group; struct ethtool_ops; - /* source back-compat hook */ + /* source back-compat hooks */ #define SET_ETHTOOL_OPS(netdev,ops) \ ( (netdev)->ethtool_ops = (ops) ) #define HAVE_ALLOC_NETDEV /* feature macro: alloc_xxxdev functions are available. */ -#define HAVE_FREE_NETDEV +#define HAVE_FREE_NETDEV /* free_netdev() */ +#define HAVE_NETDEV_PRIV /* netdev_priv() */ #define NET_XMIT_SUCCESS 0 #define NET_XMIT_DROP 1 /* skb dropped */ diff -Nru a/include/linux/netfilter.h b/include/linux/netfilter.h --- a/include/linux/netfilter.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netfilter.h Sun Apr 18 13:42:41 2004 @@ -99,6 +99,24 @@ extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; +typedef void nf_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix); + +/* Function to register/unregister log function. */ +int nf_log_register(int pf, nf_logfn *logfn); +void nf_log_unregister(int pf, nf_logfn *logfn); + +/* Calls the registered backend logging function */ +void nf_log_packet(int pf, + unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...); + /* Activate hook; either okfn or kfree_skb called, unless a hook returns NF_STOLEN (in which case, it's up to the hook to deal with the consequences). diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h --- a/include/linux/netfilter_ipv4/ip_conntrack.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netfilter_ipv4/ip_conntrack.h Sun Apr 18 13:42:41 2004 @@ -252,6 +252,9 @@ /* Call me when a conntrack is destroyed. */ extern void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack); +/* Fake conntrack entry for untracked connections */ +extern struct ip_conntrack ip_conntrack_untracked; + /* Returns new sk_buff, or NULL */ struct sk_buff * ip_ct_gather_frags(struct sk_buff *skb); diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_helper.h b/include/linux/netfilter_ipv4/ip_conntrack_helper.h --- a/include/linux/netfilter_ipv4/ip_conntrack_helper.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper.h Sun Apr 18 13:42:40 2004 @@ -35,9 +35,13 @@ extern struct ip_conntrack_helper *ip_ct_find_helper(const struct ip_conntrack_tuple *tuple); + +/* Allocate space for an expectation: this is mandatory before calling + ip_conntrack_expect_related. */ +extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void); /* Add an expected connection: can have more than one per connection */ -extern int ip_conntrack_expect_related(struct ip_conntrack *related_to, - struct ip_conntrack_expect *exp); +extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp, + struct ip_conntrack *related_to); extern int ip_conntrack_change_expect(struct ip_conntrack_expect *expect, struct ip_conntrack_tuple *newtuple); extern void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp); diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_tftp.h b/include/linux/netfilter_ipv4/ip_conntrack_tftp.h --- a/include/linux/netfilter_ipv4/ip_conntrack_tftp.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/netfilter_ipv4/ip_conntrack_tftp.h Sun Apr 18 13:42:40 2004 @@ -9,5 +9,8 @@ #define TFTP_OPCODE_READ 1 #define TFTP_OPCODE_WRITE 2 +#define TFTP_OPCODE_DATA 3 +#define TFTP_OPCODE_ACK 4 +#define TFTP_OPCODE_ERROR 5 #endif /* _IP_CT_TFTP */ diff -Nru a/include/linux/netfilter_ipv4/ip_logging.h b/include/linux/netfilter_ipv4/ip_logging.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv4/ip_logging.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,20 @@ +/* IPv4 macros for the internal logging interface. */ +#ifndef __IP_LOGGING_H +#define __IP_LOGGING_H + +#ifdef __KERNEL__ +#include +#include + +#define nf_log_ip_packet(pskb,hooknum,in,out,fmt,args...) \ + nf_log_packet(AF_INET,pskb,hooknum,in,out,fmt,##args) + +#define nf_log_ip(pfh,len,fmt,args...) \ + nf_log(AF_INET,pfh,len,fmt,##args) + +#define nf_ip_log_register(logging) nf_log_register(AF_INET,logging) +#define nf_ip_log_unregister(logging) nf_log_unregister(AF_INET,logging) + +#endif /*__KERNEL__*/ + +#endif /*__IP_LOGGING_H*/ diff -Nru a/include/linux/netfilter_ipv4/ipt_ULOG.h b/include/linux/netfilter_ipv4/ipt_ULOG.h --- a/include/linux/netfilter_ipv4/ipt_ULOG.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/netfilter_ipv4/ipt_ULOG.h Sun Apr 18 13:42:40 2004 @@ -11,6 +11,9 @@ #define NETLINK_NFLOG 5 #endif +#define ULOG_DEFAULT_NLGROUP 1 +#define ULOG_DEFAULT_QTHRESHOLD 1 + #define ULOG_MAC_LEN 80 #define ULOG_PREFIX_LEN 32 diff -Nru a/include/linux/netfilter_ipv4/ipt_conntrack.h b/include/linux/netfilter_ipv4/ipt_conntrack.h --- a/include/linux/netfilter_ipv4/ipt_conntrack.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netfilter_ipv4/ipt_conntrack.h Sun Apr 18 13:42:41 2004 @@ -10,6 +10,7 @@ #define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) #define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) /* flags, invflags: */ #define IPT_CONNTRACK_STATE 0x01 diff -Nru a/include/linux/netfilter_ipv4/ipt_state.h b/include/linux/netfilter_ipv4/ipt_state.h --- a/include/linux/netfilter_ipv4/ipt_state.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netfilter_ipv4/ipt_state.h Sun Apr 18 13:42:41 2004 @@ -4,6 +4,8 @@ #define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) #define IPT_STATE_INVALID (1 << 0) +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) + struct ipt_state_info { unsigned int statemask; diff -Nru a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h --- a/include/linux/netfilter_ipv4.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netfilter_ipv4.h Sun Apr 18 13:42:41 2004 @@ -51,6 +51,8 @@ enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, + NF_IP_PRI_CONNTRACK_DEFRAG = -400, + NF_IP_PRI_RAW = -300, NF_IP_PRI_SELINUX_FIRST = -225, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175, diff -Nru a/include/linux/netfilter_ipv6/ip6_logging.h b/include/linux/netfilter_ipv6/ip6_logging.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv6/ip6_logging.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,20 @@ +/* IPv6 macros for the nternal logging interface. */ +#ifndef __IP6_LOGGING_H +#define __IP6_LOGGING_H + +#ifdef __KERNEL__ +#include +#include + +#define nf_log_ip6_packet(pskb,hooknum,in,out,fmt,args...) \ + nf_log_packet(AF_INET6,pskb,hooknum,in,out,fmt,##args) + +#define nf_log_ip6(pfh,len,fmt,args...) \ + nf_log(AF_INET6,pfh,len,fmt,##args) + +#define nf_ip6_log_register(logging) nf_log_register(AF_INET6,logging) +#define nf_ip6_log_unregister(logging) nf_log_unregister(AF_INET6,logging) + +#endif /*__KERNEL__*/ + +#endif /*__IP6_LOGGING_H*/ diff -Nru a/include/linux/netfilter_logging.h b/include/linux/netfilter_logging.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_logging.h Sun Apr 18 13:42:41 2004 @@ -0,0 +1,33 @@ +/* Internal logging interface, which relies on the real + LOG target modules */ +#ifndef __LINUX_NETFILTER_LOGGING_H +#define __LINUX_NETFILTER_LOGGING_H + +#ifdef __KERNEL__ +#include + +struct nf_logging_t { + void (*nf_log_packet)(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *prefix); + void (*nf_log)(char *pfh, size_t len, + const char *prefix); +}; + +extern void nf_log_register(int pf, const struct nf_logging_t *logging); +extern void nf_log_unregister(int pf, const struct nf_logging_t *logging); + +extern void nf_log_packet(int pf, + struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...); +extern void nf_log(int pf, + char *pfh, size_t len, + const char *fmt, ...); +#endif /*__KERNEL__*/ + +#endif /*__LINUX_NETFILTER_LOGGING_H*/ diff -Nru a/include/linux/netlink.h b/include/linux/netlink.h --- a/include/linux/netlink.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/netlink.h Sun Apr 18 13:42:41 2004 @@ -127,6 +127,13 @@ void netlink_detachskb(struct sock *sk, struct sk_buff *skb); int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); +/* finegrained unicast helpers: */ +struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid); +struct sock *netlink_getsockbyfilp(struct file *filp); +int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock, long timeo); +void netlink_detachskb(struct sock *sk, struct sk_buff *skb); +int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol); + /* * skb should fit one page. This choice is good for headerless malloc. * diff -Nru a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h --- a/include/linux/nfsd/nfsd.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/nfsd/nfsd.h Sun Apr 18 13:42:41 2004 @@ -196,6 +196,9 @@ #define nfserr_openmode __constant_htonl(NFSERR_OPENMODE) #define nfserr_locks_held __constant_htonl(NFSERR_LOCKS_HELD) #define nfserr_op_illegal __constant_htonl(NFSERR_OP_ILLEGAL) +#define nfserr_grace __constant_htonl(NFSERR_GRACE) +#define nfserr_no_grace __constant_htonl(NFSERR_NO_GRACE) +#define nfserr_reclaim_bad __constant_htonl(NFSERR_RECLAIM_BAD) /* error codes for internal use */ /* if a request fails due to kmalloc failure, it gets dropped. diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h --- a/include/linux/nfsd/state.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/nfsd/state.h Sun Apr 18 13:42:40 2004 @@ -132,6 +132,9 @@ * release a stateowner. * so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when * close is called to reap associated byte-range locks +* so_close_lru: (open) stateowner is placed on this list instead of being +* reaped (when so_perfilestate is empty) to hold the last close replay. +* reaped by laundramat thread after lease period. */ struct nfs4_stateowner { struct list_head so_idhash; /* hash by so_id */ @@ -139,6 +142,8 @@ struct list_head so_perclient; /* nfs4_client->cl_perclient */ struct list_head so_perfilestate; /* list: nfs4_stateid */ struct list_head so_perlockowner; /* nfs4_stateid->st_perlockowner */ + struct list_head so_close_lru; /* tail queue */ + time_t so_time; /* time of placement on so_close_lru */ int so_is_open_owner; /* 1=openowner,0=lockowner */ u32 so_id; struct nfs4_client * so_client; @@ -194,6 +199,7 @@ #define OPEN_STATE 0x00000004 #define LOCK_STATE 0x00000008 #define RDWR_STATE 0x00000010 +#define CLOSE_STATE 0x00000020 #define seqid_mutating_err(err) \ (((err) != nfserr_stale_clientid) && \ @@ -209,4 +215,6 @@ unsigned int deny_type); extern void nfs4_lock_state(void); extern void nfs4_unlock_state(void); +extern int nfs4_in_grace(void); +extern int nfs4_in_no_grace(void); #endif /* NFSD4_STATE_H */ diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h --- a/include/linux/pagemap.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/pagemap.h Sun Apr 18 13:42:40 2004 @@ -139,14 +139,12 @@ return atomic_read(&nr_pagecache); } -static inline void ___add_to_page_cache(struct page *page, - struct address_space *mapping, unsigned long index) +static inline pgoff_t linear_page_index(struct vm_area_struct *vma, + unsigned long address) { - page->mapping = mapping; - page->index = index; - - mapping->nrpages++; - pagecache_acct(1); + pgoff_t pgoff = (address - vma->vm_start) >> PAGE_SHIFT; + pgoff += vma->vm_pgoff; + return pgoff >> (PAGE_CACHE_SHIFT - PAGE_SHIFT); } extern void FASTCALL(__lock_page(struct page *page)); diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/pci.h Sun Apr 18 13:42:41 2004 @@ -305,18 +305,89 @@ #define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ #define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ #define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ -#define PCI_X_DEVFN 4 /* A copy of devfn. */ -#define PCI_X_BUSNR 5 /* Bus segment number */ -#define PCI_X_STATUS 6 /* PCI-X capabilities */ -#define PCI_X_STATUS_64BIT 0x0001 /* 64-bit device */ -#define PCI_X_STATUS_133MHZ 0x0002 /* 133 MHz capable */ -#define PCI_X_STATUS_SPL_DISC 0x0004 /* Split Completion Discarded */ -#define PCI_X_STATUS_UNX_SPL 0x0008 /* Unexpected Split Completion */ -#define PCI_X_STATUS_COMPLEX 0x0010 /* Device Complexity */ -#define PCI_X_STATUS_MAX_READ 0x0060 /* Designed Maximum Memory Read Count */ -#define PCI_X_STATUS_MAX_SPLIT 0x0380 /* Design Max Outstanding Split Trans */ -#define PCI_X_STATUS_MAX_CUM 0x1c00 /* Designed Max Cumulative Read Size */ -#define PCI_X_STATUS_SPL_ERR 0x2000 /* Rcvd Split Completion Error Msg */ +#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ +#define PCI_X_STATUS 4 /* PCI-X capabilities */ +#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */ +#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */ +#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */ +#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */ +#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */ +#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */ +#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */ +#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */ +#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */ +#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */ +#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ +#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ +#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ + +/* Extended Capabilities (PCI-X 2.0 and Express) */ +#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) +#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) +#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) + +#define PCI_EXT_CAP_ID_ERR 1 +#define PCI_EXT_CAP_ID_VC 2 +#define PCI_EXT_CAP_ID_DSN 3 +#define PCI_EXT_CAP_ID_PWR 4 + +/* Advanced Error Reporting */ +#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ +#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ +#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ +#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ +#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ +#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ +#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */ +#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */ +#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */ +#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ +#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ +#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ +#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ + /* Same bits as above */ +#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */ +#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */ +#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */ +#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ +#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ +#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ +#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ +#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */ +#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */ +#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */ +#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ +#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ +#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ +#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ +#define PCI_ERR_ROOT_STATUS 48 +#define PCI_ERR_ROOT_COR_SRC 52 +#define PCI_ERR_ROOT_SRC 54 + +/* Virtual Channel */ +#define PCI_VC_PORT_REG1 4 +#define PCI_VC_PORT_REG2 8 +#define PCI_VC_PORT_CTRL 12 +#define PCI_VC_PORT_STATUS 14 +#define PCI_VC_RES_CAP 16 +#define PCI_VC_RES_CTRL 20 +#define PCI_VC_RES_STATUS 26 + +/* Power Budgeting */ +#define PCI_PWR_DSR 4 /* Data Select Register */ +#define PCI_PWR_DATA 8 /* Data Register */ +#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */ +#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */ +#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */ +#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */ +#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */ +#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ +#define PCI_PWR_CAP 12 /* Capability */ +#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ /* Include the ID list */ @@ -403,6 +474,8 @@ unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE]; + int cfg_size; /* Size of configuration space */ + /* * Instead of touching interrupt line and base address registers * directly, use the values stored here. They might be different! @@ -602,6 +675,7 @@ struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); int pci_find_capability (struct pci_dev *dev, int cap); +int pci_find_ext_capability (struct pci_dev *dev, int cap); struct pci_bus * pci_find_next_bus(const struct pci_bus *from); struct pci_dev *pci_get_device (unsigned int vendor, unsigned int device, struct pci_dev *from); @@ -774,6 +848,7 @@ static inline int pci_register_driver(struct pci_driver *drv) { return 0;} static inline void pci_unregister_driver(struct pci_driver *drv) { } static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } +static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } /* Power management related routines */ diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/pci_ids.h Sun Apr 18 13:42:41 2004 @@ -2087,6 +2087,7 @@ #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 #define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 #define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582 +#define PCI_DEVICE_ID_INTEL_SMCH 0x3590 #define PCI_DEVICE_ID_INTEL_80310 0x530d #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 diff -Nru a/include/linux/quota.h b/include/linux/quota.h --- a/include/linux/quota.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/quota.h Sun Apr 18 13:42:41 2004 @@ -138,6 +138,10 @@ #include #include +/* Maximal numbers of writes for quota operation (insert/delete/update) + * (over all formats) - info block, 4 pointer blocks, data block */ +#define DQUOT_MAX_WRITES 6 + /* * Data for one user/group kept in memory */ @@ -168,22 +172,21 @@ } u; }; +struct super_block; + #define DQF_MASK 0xffff /* Mask for format specific flags */ #define DQF_INFO_DIRTY_B 16 #define DQF_ANY_DQUOT_DIRTY_B 17 #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */ #define DQF_ANY_DQUOT_DIRTY (1 << DQF_ANY_DQUOT_DIRTY_B) /* Is any dquot dirty? */ -extern inline void mark_info_dirty(struct mem_dqinfo *info) -{ - set_bit(DQF_INFO_DIRTY_B, &info->dqi_flags); -} - +extern void mark_info_dirty(struct super_block *sb, int type); #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags) #define info_any_dquot_dirty(info) test_bit(DQF_ANY_DQUOT_DIRTY_B, &(info)->dqi_flags) #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info)) #define sb_dqopt(sb) (&(sb)->s_dquot) +#define sb_dqinfo(sb, type) (sb_dqopt(sb)->info+(type)) struct dqstats { int lookups; @@ -200,15 +203,13 @@ #define NR_DQHASH 43 /* Just an arbitrary number */ -#define DQ_MOD_B 0 -#define DQ_BLKS_B 1 -#define DQ_INODES_B 2 -#define DQ_FAKE_B 3 - -#define DQ_MOD (1 << DQ_MOD_B) /* dquot modified since read */ -#define DQ_BLKS (1 << DQ_BLKS_B) /* uid/gid has been warned about blk limit */ -#define DQ_INODES (1 << DQ_INODES_B) /* uid/gid has been warned about inode limit */ -#define DQ_FAKE (1 << DQ_FAKE_B) /* no limits only usage */ +#define DQ_MOD_B 0 /* dquot modified since read */ +#define DQ_BLKS_B 1 /* uid/gid has been warned about blk limit */ +#define DQ_INODES_B 2 /* uid/gid has been warned about inode limit */ +#define DQ_FAKE_B 3 /* no limits only usage */ +#define DQ_READ_B 4 /* dquot was read into memory */ +#define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */ +#define DQ_WAITFREE_B 6 /* dquot being waited (by invalidate_dquots) */ struct dquot { struct list_head dq_hash; /* Hash list in memory */ @@ -216,8 +217,7 @@ struct list_head dq_free; /* Free list element */ struct semaphore dq_lock; /* dquot IO lock */ atomic_t dq_count; /* Use count */ - - /* fields after this point are cleared when invalidating */ + wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ struct super_block *dq_sb; /* superblock this applies to */ unsigned int dq_id; /* ID this applies to (uid, gid) */ loff_t dq_off; /* Offset of dquot on disk */ @@ -238,19 +238,22 @@ int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */ int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */ int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */ - int (*commit_dqblk)(struct dquot *dquot); /* Write (or delete) structure for one user */ + int (*commit_dqblk)(struct dquot *dquot); /* Write structure for one user */ + int (*release_dqblk)(struct dquot *dquot); /* Called when last reference to dquot is being dropped */ }; /* Operations working with dquots */ struct dquot_operations { - void (*initialize) (struct inode *, int); - void (*drop) (struct inode *); + int (*initialize) (struct inode *, int); + int (*drop) (struct inode *); int (*alloc_space) (struct inode *, qsize_t, int); int (*alloc_inode) (const struct inode *, unsigned long); - void (*free_space) (struct inode *, qsize_t); - void (*free_inode) (const struct inode *, unsigned long); + int (*free_space) (struct inode *, qsize_t); + int (*free_inode) (const struct inode *, unsigned long); int (*transfer) (struct inode *, struct iattr *); - int (*write_dquot) (struct dquot *); + int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ + int (*mark_dirty) (struct dquot *); /* Dquot is marked dirty */ + int (*write_info) (struct super_block *, int); /* Write of quota "superblock" */ }; /* Operations handling requests from userspace */ @@ -289,10 +292,7 @@ }; /* Inline would be better but we need to dereference super_block which is not defined yet */ -#define mark_dquot_dirty(dquot) do {\ - set_bit(DQF_ANY_DQUOT_DIRTY_B, &(sb_dqopt((dquot)->dq_sb)->info[(dquot)->dq_type].dqi_flags));\ - set_bit(DQ_MOD_B, &(dquot)->dq_flags);\ -} while (0) +int mark_dquot_dirty(struct dquot *dquot); #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags) @@ -304,7 +304,6 @@ int register_quota_format(struct quota_format_type *fmt); void unregister_quota_format(struct quota_format_type *fmt); -void init_dquot_operations(struct dquot_operations *fsdqops); struct quota_module_name { int qm_fmt_id; diff -Nru a/include/linux/quotaops.h b/include/linux/quotaops.h --- a/include/linux/quotaops.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/quotaops.h Sun Apr 18 13:42:40 2004 @@ -22,16 +22,31 @@ */ extern void sync_dquots(struct super_block *sb, int type); -extern void dquot_initialize(struct inode *inode, int type); -extern void dquot_drop(struct inode *inode); +extern int dquot_initialize(struct inode *inode, int type); +extern int dquot_drop(struct inode *inode); -extern int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); -extern int dquot_alloc_inode(const struct inode *inode, unsigned long number); +extern int dquot_alloc_space(struct inode *inode, qsize_t number, int prealloc); +extern int dquot_alloc_inode(const struct inode *inode, unsigned long number); -extern void dquot_free_space(struct inode *inode, qsize_t number); -extern void dquot_free_inode(const struct inode *inode, unsigned long number); +extern int dquot_free_space(struct inode *inode, qsize_t number); +extern int dquot_free_inode(const struct inode *inode, unsigned long number); -extern int dquot_transfer(struct inode *inode, struct iattr *iattr); +extern int dquot_transfer(struct inode *inode, struct iattr *iattr); +extern int dquot_commit(struct dquot *dquot); +extern int dquot_acquire(struct dquot *dquot); +extern int dquot_release(struct dquot *dquot); +extern int dquot_commit_info(struct super_block *sb, int type); +extern int dquot_mark_dquot_dirty(struct dquot *dquot); + +extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path); +extern int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry); +extern int vfs_quota_off(struct super_block *sb, int type); +#define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type) +extern int vfs_quota_sync(struct super_block *sb, int type); +extern int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +extern int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +extern int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); +extern int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); /* * Operations supported for diskquotas. @@ -42,6 +57,8 @@ #define sb_dquot_ops (&dquot_operations) #define sb_quotactl_ops (&vfs_quotactl_ops) +/* It is better to call this function outside of any transaction as it might + * need a lot of space in journal for dquot structure allocation. */ static __inline__ void DQUOT_INIT(struct inode *inode) { BUG_ON(!inode->i_sb); @@ -49,6 +66,7 @@ inode->i_sb->dq_op->initialize(inode, -1); } +/* The same as with DQUOT_INIT */ static __inline__ void DQUOT_DROP(struct inode *inode) { if (IS_QUOTAINIT(inode)) { @@ -57,6 +75,8 @@ } } +/* The following allocation/freeing/transfer functions *must* be called inside + * a transaction (deadlocks possible otherwise) */ static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr) { if (sb_any_quota_enabled(inode->i_sb)) { @@ -137,6 +157,7 @@ return 0; } +/* The following two functions cannot be called inside a transaction */ #define DQUOT_SYNC(sb) sync_dquots(sb, -1) static __inline__ int DQUOT_OFF(struct super_block *sb) diff -Nru a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h --- a/include/linux/reiserfs_fs_sb.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/reiserfs_fs_sb.h Sun Apr 18 13:42:41 2004 @@ -208,6 +208,7 @@ unsigned int s_journal_trans_max ; /* max number of blocks in a transaction. */ unsigned int s_journal_max_batch ; /* max number of blocks to batch into a trans */ unsigned int s_journal_max_commit_age ; /* in seconds, how old can an async commit be */ + unsigned int s_journal_default_max_commit_age ; /* the default for the max commit age */ unsigned int s_journal_max_trans_age ; /* in seconds, how old can a transaction be */ struct reiserfs_journal_cnode *j_cnode_free_list ; @@ -481,6 +482,7 @@ #define SB_JOURNAL_TRANS_MAX(s) (SB_JOURNAL(s)->s_journal_trans_max) #define SB_JOURNAL_MAX_BATCH(s) (SB_JOURNAL(s)->s_journal_max_batch) #define SB_JOURNAL_MAX_COMMIT_AGE(s) (SB_JOURNAL(s)->s_journal_max_commit_age) +#define SB_JOURNAL_DEFAULT_MAX_COMMIT_AGE(s) (SB_JOURNAL(s)->s_journal_default_max_commit_age) #define SB_JOURNAL_MAX_TRANS_AGE(s) (SB_JOURNAL(s)->s_journal_max_trans_age) /* A safe version of the "bdevname", which returns the "s_id" field of diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h --- a/include/linux/rtnetlink.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/rtnetlink.h Sun Apr 18 13:42:41 2004 @@ -47,7 +47,11 @@ #define RTM_NEWPREFIX (RTM_BASE+36) #define RTM_GETPREFIX (RTM_BASE+38) -#define RTM_MAX (RTM_BASE+39) +#define RTM_GETMULTICAST (RTM_BASE+42) + +#define RTM_GETANYCAST (RTM_BASE+46) + +#define RTM_MAX (RTM_BASE+47) /* Generic structure for encapsulation of optional route information. @@ -340,7 +344,8 @@ IFA_LABEL, IFA_BROADCAST, IFA_ANYCAST, - IFA_CACHEINFO + IFA_CACHEINFO, + IFA_MULTICAST }; #define IFA_MAX IFA_CACHEINFO diff -Nru a/include/linux/swap.h b/include/linux/swap.h --- a/include/linux/swap.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/swap.h Sun Apr 18 13:42:40 2004 @@ -181,8 +181,6 @@ extern int shmem_unuse(swp_entry_t entry, struct page *page); #endif /* CONFIG_MMU */ -extern void swap_unplug_io_fn(struct backing_dev_info *); - #ifdef CONFIG_SWAP /* linux/mm/page_io.c */ extern int swap_readpage(struct file *, struct page *); @@ -218,7 +216,7 @@ extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); -struct backing_dev_info; +extern void swap_unplug_io_fn(struct page *); extern struct swap_list_t swap_list; extern spinlock_t swaplock; @@ -252,6 +250,7 @@ #define move_from_swap_cache(p, i, m) 1 #define __delete_from_swap_cache(p) /*NOTHING*/ #define delete_from_swap_cache(p) /*NOTHING*/ +#define swap_unplug_io_fn(p) /*NOTHING*/ static inline int remove_exclusive_swap_page(struct page *p) { diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/sysctl.h Sun Apr 18 13:42:41 2004 @@ -131,6 +131,7 @@ KERN_PRINTK_RATELIMIT_BURST=61, /* int: tune printk ratelimiting */ KERN_PTY=62, /* dir: pty driver */ KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */ + KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */ }; diff -Nru a/include/linux/udp.h b/include/linux/udp.h --- a/include/linux/udp.h Sun Apr 18 13:42:40 2004 +++ b/include/linux/udp.h Sun Apr 18 13:42:40 2004 @@ -31,6 +31,7 @@ #define UDP_ENCAP 100 /* Set the socket to accept encapsulated packets */ /* UDP encapsulation types */ +#define UDP_ENCAP_ESPINUDP_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ #define UDP_ENCAP_ESPINUDP 2 /* draft-ietf-ipsec-udp-encaps-06 */ #ifdef __KERNEL__ diff -Nru a/include/linux/wireless.h b/include/linux/wireless.h --- a/include/linux/wireless.h Sun Apr 18 13:42:41 2004 +++ b/include/linux/wireless.h Sun Apr 18 13:42:41 2004 @@ -438,7 +438,7 @@ */ struct iw_point { - caddr_t pointer; /* Pointer to the data (in user space) */ + void __user *pointer; /* Pointer to the data (in user space) */ __u16 length; /* number of fields or size in bytes */ __u16 flags; /* Optional params */ }; diff -Nru a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h --- a/include/net/bluetooth/hci_core.h Sun Apr 18 13:42:41 2004 +++ b/include/net/bluetooth/hci_core.h Sun Apr 18 13:42:41 2004 @@ -515,9 +515,9 @@ #define HCI_SFLT_MAX_OGF 5 struct hci_sec_filter { - unsigned long type_mask; - unsigned long event_mask[2]; - unsigned long ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; + __u32 type_mask; + __u32 event_mask[2]; + __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; }; /* ----- HCI requests ----- */ diff -Nru a/include/net/irda/ali-ircc.h b/include/net/irda/ali-ircc.h --- a/include/net/irda/ali-ircc.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,228 +0,0 @@ -/********************************************************************* - * - * Filename: ali-ircc.h - * Version: 0.5 - * Description: Driver for the ALI M1535D and M1543C FIR Controller - * Status: Experimental. - * Author: Benjamin Kong - * Created at: 2000/10/16 03:46PM - * Modified at: 2001/1/3 02:56PM - * Modified by: Benjamin Kong - * - * Copyright (c) 2000 Benjamin Kong - * All Rights Reserved - * - * 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. - * - ********************************************************************/ - -#ifndef ALI_IRCC_H -#define ALI_IRCC_H - -#include - -#include -#include -#include - -/* SIR Register */ -/* Usr definition of linux/serial_reg.h */ - -/* FIR Register */ -#define BANK0 0x20 -#define BANK1 0x21 -#define BANK2 0x22 -#define BANK3 0x23 - -#define FIR_MCR 0x07 /* Master Control Register */ - -/* Bank 0 */ -#define FIR_DR 0x00 /* Alias 0, FIR Data Register (R/W) */ -#define FIR_IER 0x01 /* Alias 1, FIR Interrupt Enable Register (R/W) */ -#define FIR_IIR 0x02 /* Alias 2, FIR Interrupt Identification Register (Read only) */ -#define FIR_LCR_A 0x03 /* Alias 3, FIR Line Control Register A (R/W) */ -#define FIR_LCR_B 0x04 /* Alias 4, FIR Line Control Register B (R/W) */ -#define FIR_LSR 0x05 /* Alias 5, FIR Line Status Register (R/W) */ -#define FIR_BSR 0x06 /* Alias 6, FIR Bus Status Register (Read only) */ - - - /* Alias 1 */ - #define IER_FIFO 0x10 /* FIR FIFO Interrupt Enable */ - #define IER_TIMER 0x20 /* Timer Interrupt Enable */ - #define IER_EOM 0x40 /* End of Message Interrupt Enable */ - #define IER_ACT 0x80 /* Active Frame Interrupt Enable */ - - /* Alias 2 */ - #define IIR_FIFO 0x10 /* FIR FIFO Interrupt */ - #define IIR_TIMER 0x20 /* Timer Interrupt */ - #define IIR_EOM 0x40 /* End of Message Interrupt */ - #define IIR_ACT 0x80 /* Active Frame Interrupt */ - - /* Alias 3 */ - #define LCR_A_FIFO_RESET 0x80 /* FIFO Reset */ - - /* Alias 4 */ - #define LCR_B_BW 0x10 /* Brick Wall */ - #define LCR_B_SIP 0x20 /* SIP Enable */ - #define LCR_B_TX_MODE 0x40 /* Transmit Mode */ - #define LCR_B_RX_MODE 0x80 /* Receive Mode */ - - /* Alias 5 */ - #define LSR_FIR_LSA 0x00 /* FIR Line Status Address */ - #define LSR_FRAME_ABORT 0x08 /* Frame Abort */ - #define LSR_CRC_ERROR 0x10 /* CRC Error */ - #define LSR_SIZE_ERROR 0x20 /* Size Error */ - #define LSR_FRAME_ERROR 0x40 /* Frame Error */ - #define LSR_FIFO_UR 0x80 /* FIFO Underrun */ - #define LSR_FIFO_OR 0x80 /* FIFO Overrun */ - - /* Alias 6 */ - #define BSR_FIFO_NOT_EMPTY 0x80 /* FIFO Not Empty */ - -/* Bank 1 */ -#define FIR_CR 0x00 /* Alias 0, FIR Configuration Register (R/W) */ -#define FIR_FIFO_TR 0x01 /* Alias 1, FIR FIFO Threshold Register (R/W) */ -#define FIR_DMA_TR 0x02 /* Alias 2, FIR DMA Threshold Register (R/W) */ -#define FIR_TIMER_IIR 0x03 /* Alias 3, FIR Timer interrupt interval register (W/O) */ -#define FIR_FIFO_FR 0x03 /* Alias 3, FIR FIFO Flag register (R/O) */ -#define FIR_FIFO_RAR 0x04 /* Alias 4, FIR FIFO Read Address register (R/O) */ -#define FIR_FIFO_WAR 0x05 /* Alias 5, FIR FIFO Write Address register (R/O) */ -#define FIR_TR 0x06 /* Alias 6, Test REgister (W/O) */ - - /* Alias 0 */ - #define CR_DMA_EN 0x01 /* DMA Enable */ - #define CR_DMA_BURST 0x02 /* DMA Burst Mode */ - #define CR_TIMER_EN 0x08 /* Timer Enable */ - - /* Alias 3 */ - #define TIMER_IIR_500 0x00 /* 500 us */ - #define TIMER_IIR_1ms 0x01 /* 1 ms */ - #define TIMER_IIR_2ms 0x02 /* 2 ms */ - #define TIMER_IIR_4ms 0x03 /* 4 ms */ - -/* Bank 2 */ -#define FIR_IRDA_CR 0x00 /* Alias 0, IrDA Control Register (R/W) */ -#define FIR_BOF_CR 0x01 /* Alias 1, BOF Count Register (R/W) */ -#define FIR_BW_CR 0x02 /* Alias 2, Brick Wall Count Register (R/W) */ -#define FIR_TX_DSR_HI 0x03 /* Alias 3, TX Data Size Register (high) (R/W) */ -#define FIR_TX_DSR_LO 0x04 /* Alias 4, TX Data Size Register (low) (R/W) */ -#define FIR_RX_DSR_HI 0x05 /* Alias 5, RX Data Size Register (high) (R/W) */ -#define FIR_RX_DSR_LO 0x06 /* Alias 6, RX Data Size Register (low) (R/W) */ - - /* Alias 0 */ - #define IRDA_CR_HDLC1152 0x80 /* 1.152Mbps HDLC Select */ - #define IRDA_CR_CRC 0X40 /* CRC Select. */ - #define IRDA_CR_HDLC 0x20 /* HDLC select. */ - #define IRDA_CR_HP_MODE 0x10 /* HP mode (read only) */ - #define IRDA_CR_SD_ST 0x08 /* SD/MODE State. */ - #define IRDA_CR_FIR_SIN 0x04 /* FIR SIN Select. */ - #define IRDA_CR_ITTX_0 0x02 /* SOUT State. IRTX force to 0 */ - #define IRDA_CR_ITTX_1 0x03 /* SOUT State. IRTX force to 1 */ - -/* Bank 3 */ -#define FIR_ID_VR 0x00 /* Alias 0, FIR ID Version Register (R/O) */ -#define FIR_MODULE_CR 0x01 /* Alias 1, FIR Module Control Register (R/W) */ -#define FIR_IO_BASE_HI 0x02 /* Alias 2, FIR Higher I/O Base Address Register (R/O) */ -#define FIR_IO_BASE_LO 0x03 /* Alias 3, FIR Lower I/O Base Address Register (R/O) */ -#define FIR_IRQ_CR 0x04 /* Alias 4, FIR IRQ Channel Register (R/O) */ -#define FIR_DMA_CR 0x05 /* Alias 5, FIR DMA Channel Register (R/O) */ - -struct ali_chip { - char *name; - int cfg[2]; - unsigned char entr1; - unsigned char entr2; - unsigned char cid_index; - unsigned char cid_value; - int (*probe)(struct ali_chip *chip, chipio_t *info); - int (*init)(struct ali_chip *chip, chipio_t *info); -}; -typedef struct ali_chip ali_chip_t; - - -/* DMA modes needed */ -#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ -#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ - -#define MAX_TX_WINDOW 7 -#define MAX_RX_WINDOW 7 - -#define TX_FIFO_Threshold 8 -#define RX_FIFO_Threshold 1 -#define TX_DMA_Threshold 1 -#define RX_DMA_Threshold 1 - -/* For storing entries in the status FIFO */ - -struct st_fifo_entry { - int status; - int len; -}; - -struct st_fifo { - struct st_fifo_entry entries[MAX_RX_WINDOW]; - int pending_bytes; - int head; - int tail; - int len; -}; - -struct frame_cb { - void *start; /* Start of frame in DMA mem */ - int len; /* Lenght of frame in DMA mem */ -}; - -struct tx_fifo { - struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ - int ptr; /* Currently being sent */ - int len; /* Lenght of queue */ - int free; /* Next free slot */ - void *tail; /* Next free start in DMA mem */ -}; - -/* Private data for each instance */ -struct ali_ircc_cb { - - struct st_fifo st_fifo; /* Info about received frames */ - struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ - - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are binded to */ - struct qos_info qos; /* QoS capabilities for this device */ - - chipio_t io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - __u8 ier; /* Interrupt enable register */ - - __u8 InterruptID; /* Interrupt ID */ - __u8 BusStatus; /* Bus Status */ - __u8 LineStatus; /* Line Status */ - - unsigned char rcvFramesOverflow; - - struct timeval stamp; - struct timeval now; - - spinlock_t lock; /* For serializing operations */ - - __u32 new_speed; - int index; /* Instance index */ - - unsigned char fifo_opti_buf; - - struct pm_dev *dev; -}; - -static inline void switch_bank(int iobase, int bank) -{ - outb(bank, iobase+FIR_MCR); -} - -#endif /* ALI_IRCC_H */ diff -Nru a/include/net/irda/au1000_ircc.h b/include/net/irda/au1000_ircc.h --- a/include/net/irda/au1000_ircc.h Sun Apr 18 13:42:40 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,127 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Au1000 IrDA driver. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS 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 AU1000_IRCC_H -#define AU1000_IRCC_H - -#include - -#include -#include -#include - -#define NUM_IR_IFF 1 -#define NUM_IR_DESC 64 -#define RING_SIZE_4 0x0 -#define RING_SIZE_16 0x3 -#define RING_SIZE_64 0xF -#define MAX_NUM_IR_DESC 64 -#define MAX_BUF_SIZE 2048 - -#define BPS_115200 0 -#define BPS_57600 1 -#define BPS_38400 2 -#define BPS_19200 5 -#define BPS_9600 11 -#define BPS_2400 47 - -/* Ring descriptor flags */ -#define AU_OWN (1<<7) /* tx,rx */ - -#define IR_DIS_CRC (1<<6) /* tx */ -#define IR_BAD_CRC (1<<5) /* tx */ -#define IR_NEED_PULSE (1<<4) /* tx */ -#define IR_FORCE_UNDER (1<<3) /* tx */ -#define IR_DISABLE_TX (1<<2) /* tx */ -#define IR_HW_UNDER (1<<0) /* tx */ -#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) - -#define IR_PHY_ERROR (1<<6) /* rx */ -#define IR_CRC_ERROR (1<<5) /* rx */ -#define IR_MAX_LEN (1<<4) /* rx */ -#define IR_FIFO_OVER (1<<3) /* rx */ -#define IR_SIR_ERROR (1<<2) /* rx */ -#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ - IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) - -typedef struct db_dest { - struct db_dest *pnext; - volatile u32 *vaddr; - dma_addr_t dma_addr; -} db_dest_t; - - -typedef struct ring_desc { - u8 count_0; /* 7:0 */ - u8 count_1; /* 12:8 */ - u8 reserved; - u8 flags; - u8 addr_0; /* 7:0 */ - u8 addr_1; /* 15:8 */ - u8 addr_2; /* 23:16 */ - u8 addr_3; /* 31:24 */ -} ring_dest_t; - - -/* Private data for each instance */ -struct au1k_private { - - db_dest_t *pDBfree; - db_dest_t db[2*NUM_IR_DESC]; - volatile ring_dest_t *rx_ring[NUM_IR_DESC]; - volatile ring_dest_t *tx_ring[NUM_IR_DESC]; - db_dest_t *rx_db_inuse[NUM_IR_DESC]; - db_dest_t *tx_db_inuse[NUM_IR_DESC]; - u32 rx_head; - u32 tx_head; - u32 tx_tail; - u32 tx_full; - - iobuff_t rx_buff; - - struct net_device *netdev; - struct net_device_stats stats; - - struct timeval stamp; - struct timeval now; - struct qos_info qos; - struct irlap_cb *irlap; - - u8 open; - u32 speed; - u32 newspeed; - - u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ - struct timer_list timer; - - spinlock_t lock; /* For serializing operations */ - struct pm_dev *dev; -}; -#endif /* AU1000_IRCC_H */ diff -Nru a/include/net/irda/irda-usb.h b/include/net/irda/irda-usb.h --- a/include/net/irda/irda-usb.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,163 +0,0 @@ -/***************************************************************************** - * - * Filename: irda-usb.h - * Version: 0.9b - * Description: IrDA-USB Driver - * Status: Experimental - * Author: Dag Brattli - * - * Copyright (C) 2001, Roman Weissgaerber - * Copyright (C) 2000, Dag Brattli - * Copyright (C) 2001, Jean Tourrilhes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - *****************************************************************************/ - -#include - -#include -#include /* struct irlap_cb */ - -#define RX_COPY_THRESHOLD 200 -#define IRDA_USB_MAX_MTU 2051 -#define IRDA_USB_SPEED_MTU 64 /* Weird, but work like this */ - -/* Maximum number of active URB on the Rx path - * This is the amount of buffers the we keep between the USB harware and the - * IrDA stack. - * - * Note : the network layer does also queue the packets between us and the - * IrDA stack, and is actually pretty fast and efficient in doing that. - * Therefore, we don't need to have a large number of URBs, and we can - * perfectly live happy with only one. We certainly don't need to keep the - * full IrTTP window around here... - * I repeat for those who have trouble to understand : 1 URB is plenty - * good enough to handle back-to-back (brickwalled) frames. I tried it, - * it works (it's the hardware that has trouble doing it). - * - * Having 2 URBs would allow the USB stack to process one URB while we take - * care of the other and then swap the URBs... - * On the other hand, increasing the number of URB will have penalities - * in term of latency and will interact with the link management in IrLAP... - * Jean II */ -#define IU_MAX_ACTIVE_RX_URBS 1 /* Don't touch !!! */ - -/* When a Rx URB is passed back to us, we can't reuse it immediately, - * because it may still be referenced by the USB layer. Therefore we - * need to keep one extra URB in the Rx path. - * Jean II */ -#define IU_MAX_RX_URBS (IU_MAX_ACTIVE_RX_URBS + 1) - -/* Various ugly stuff to try to workaround generic problems */ -/* Send speed command in case of timeout, just for trying to get things sane */ -#define IU_BUG_KICK_TIMEOUT -/* Show the USB class descriptor */ -#undef IU_DUMP_CLASS_DESC -/* Assume a minimum round trip latency for USB transfer (in us)... - * USB transfer are done in the next USB slot if there is no traffic - * (1/19 msec) and is done at 12 Mb/s : - * Waiting for slot + tx = (53us + 16us) * 2 = 137us minimum. - * Rx notification will only be done at the end of the USB frame period : - * OHCI : frame period = 1ms - * UHCI : frame period = 1ms, but notification can take 2 or 3 ms :-( - * EHCI : frame period = 125us */ -#define IU_USB_MIN_RTT 500 /* This should be safe in most cases */ - -/* Inbound header */ -#define MEDIA_BUSY 0x80 - -#define SPEED_2400 0x01 -#define SPEED_9600 0x02 -#define SPEED_19200 0x03 -#define SPEED_38400 0x04 -#define SPEED_57600 0x05 -#define SPEED_115200 0x06 -#define SPEED_576000 0x07 -#define SPEED_1152000 0x08 -#define SPEED_4000000 0x09 - -/* Basic capabilities */ -#define IUC_DEFAULT 0x00 /* Basic device compliant with 1.0 spec */ -/* Main bugs */ -#define IUC_SPEED_BUG 0x01 /* Device doesn't set speed after the frame */ -#define IUC_NO_WINDOW 0x02 /* Device doesn't behave with big Rx window */ -#define IUC_NO_TURN 0x04 /* Device doesn't do turnaround by itself */ -/* Not currently used */ -#define IUC_SIR_ONLY 0x08 /* Device doesn't behave at FIR speeds */ -#define IUC_SMALL_PKT 0x10 /* Device doesn't behave with big Rx packets */ -#define IUC_MAX_WINDOW 0x20 /* Device underestimate the Rx window */ -#define IUC_MAX_XBOFS 0x40 /* Device need more xbofs than advertised */ - -/* USB class definitions */ -#define USB_IRDA_HEADER 0x01 -#define USB_CLASS_IRDA 0x02 /* USB_CLASS_APP_SPEC subclass */ -#define USB_DT_IRDA 0x21 - -struct irda_class_desc { - __u8 bLength; - __u8 bDescriptorType; - __u16 bcdSpecRevision; - __u8 bmDataSize; - __u8 bmWindowSize; - __u8 bmMinTurnaroundTime; - __u16 wBaudRate; - __u8 bmAdditionalBOFs; - __u8 bIrdaRateSniff; - __u8 bMaxUnicastList; -} __attribute__ ((packed)); - -/* class specific interface request to get the IrDA-USB class descriptor - * (6.2.5, USB-IrDA class spec 1.0) */ - -#define IU_REQ_GET_CLASS_DESC 0x06 - -struct irda_usb_cb { - struct irda_class_desc *irda_desc; - struct usb_device *usbdev; /* init: probe_irda */ - struct usb_interface *usbintf; /* init: probe_irda */ - int netopen; /* Device is active for network */ - int present; /* Device is present on the bus */ - __u32 capability; /* Capability of the hardware */ - __u8 bulk_in_ep; /* Rx Endpoint assignments */ - __u8 bulk_out_ep; /* Tx Endpoint assignments */ - __u16 bulk_out_mtu; /* Max Tx packet size in bytes */ - __u8 bulk_int_ep; /* Interrupt Endpoint assignments */ - - wait_queue_head_t wait_q; /* for timeouts */ - - struct urb *rx_urb[IU_MAX_RX_URBS]; /* URBs used to receive data frames */ - struct urb *idle_rx_urb; /* Pointer to idle URB in Rx path */ - struct urb *tx_urb; /* URB used to send data frames */ - struct urb *speed_urb; /* URB used to send speed commands */ - - struct net_device *netdev; /* Yes! we are some kind of netdev. */ - struct net_device_stats stats; - struct irlap_cb *irlap; /* The link layer we are binded to */ - struct qos_info qos; - hashbin_t *tx_list; /* Queued transmit skb's */ - char *speed_buff; /* Buffer for speed changes */ - - struct timeval stamp; - struct timeval now; - - spinlock_t lock; /* For serializing operations */ - - __u16 xbofs; /* Current xbofs setting */ - __s16 new_xbofs; /* xbofs we need to set */ - __u32 speed; /* Current speed */ - __s32 new_speed; /* speed we need to set */ -}; - diff -Nru a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h --- a/include/net/irda/irlan_common.h Sun Apr 18 13:42:41 2004 +++ b/include/net/irda/irlan_common.h Sun Apr 18 13:42:41 2004 @@ -219,7 +219,6 @@ __u16 value_len); int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len); -void print_ret_code(__u8 code); #endif diff -Nru a/include/net/irda/irlan_eth.h b/include/net/irda/irlan_eth.h --- a/include/net/irda/irlan_eth.h Sun Apr 18 13:42:41 2004 +++ b/include/net/irda/irlan_eth.h Sun Apr 18 13:42:41 2004 @@ -25,16 +25,9 @@ #ifndef IRLAN_ETH_H #define IRLAN_ETH_H -void irlan_eth_setup(struct net_device *dev); -int irlan_eth_open(struct net_device *dev); -int irlan_eth_close(struct net_device *dev); +struct net_device *alloc_irlandev(const char *name); int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb); -int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev); void irlan_eth_flow_indication( void *instance, void *sap, LOCAL_FLOW flow); void irlan_eth_send_gratuitous_arp(struct net_device *dev); - -void irlan_eth_set_multicast_list( struct net_device *dev); -struct net_device_stats *irlan_eth_get_stats(struct net_device *dev); - #endif diff -Nru a/include/net/irda/irlan_filter.h b/include/net/irda/irlan_filter.h --- a/include/net/irda/irlan_filter.h Sun Apr 18 13:42:40 2004 +++ b/include/net/irda/irlan_filter.h Sun Apr 18 13:42:40 2004 @@ -27,7 +27,7 @@ void irlan_check_command_param(struct irlan_cb *self, char *param, char *value); -void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb); +void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb); int irlan_print_filter(struct seq_file *seq, int filter_type); #endif /* IRLAN_FILTER_H */ diff -Nru a/include/net/irda/irport.h b/include/net/irda/irport.h --- a/include/net/irda/irport.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,90 +0,0 @@ -/********************************************************************* - * - * Filename: irport.h - * Version: 0.1 - * Description: Serial driver for IrDA - * Status: Experimental. - * Author: Dag Brattli - * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Fri Jan 14 10:21:10 2000 - * Modified by: Dag Brattli - * - * Copyright (c) 1997, 1998-2000 Dag Brattli - * All Rights Reserved. - * - * 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef IRPORT_H -#define IRPORT_H - -#include -#include -#include -#include - -#include - -#define SPEED_DEFAULT 9600 -#define SPEED_MAX 115200 - -/* - * These are the supported serial types. - */ -#define PORT_UNKNOWN 0 -#define PORT_8250 1 -#define PORT_16450 2 -#define PORT_16550 3 -#define PORT_16550A 4 -#define PORT_CIRRUS 5 -#define PORT_16650 6 -#define PORT_MAX 6 - -#define FRAME_MAX_SIZE 2048 - -struct irport_cb { - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are attached to */ - - chipio_t io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - struct qos_info qos; /* QoS capabilities for this device */ - dongle_t *dongle; /* Dongle driver */ - - __u32 flags; /* Interface flags */ - __u32 new_speed; - int mode; - int index; /* Instance index */ - int transmitting; /* Are we transmitting ? */ - - spinlock_t lock; /* For serializing operations */ - - /* For piggyback drivers */ - void *priv; - void (*change_speed)(void *priv, __u32 speed); - int (*interrupt)(int irq, void *dev_id, struct pt_regs *regs); -}; - -struct irport_cb *irport_open(int i, unsigned int iobase, unsigned int irq); -int irport_close(struct irport_cb *self); -void irport_start(struct irport_cb *self); -void irport_stop(struct irport_cb *self); -void irport_change_speed(void *priv, __u32 speed); -irqreturn_t irport_interrupt(int irq, void *dev_id, struct pt_regs *regs); -int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); -int irport_net_open(struct net_device *dev); -int irport_net_close(struct net_device *dev); - -#endif /* IRPORT_H */ diff -Nru a/include/net/irda/nsc-ircc.h b/include/net/irda/nsc-ircc.h --- a/include/net/irda/nsc-ircc.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,277 +0,0 @@ -/********************************************************************* - * - * Filename: nsc-ircc.h - * Version: - * Description: - * Status: Experimental. - * Author: Dag Brattli - * Created at: Fri Nov 13 14:37:40 1998 - * Modified at: Sun Jan 23 17:47:00 2000 - * Modified by: Dag Brattli - * - * Copyright (c) 1998-2000 Dag Brattli - * Copyright (c) 1998 Lichen Wang, - * Copyright (c) 1998 Actisys Corp., www.actisys.com - * All Rights Reserved - * - * 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef NSC_IRCC_H -#define NSC_IRCC_H - -#include - -#include -#include -#include - -/* DMA modes needed */ -#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ -#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ - -/* Config registers for the '108 */ -#define CFG_108_BAIC 0x00 -#define CFG_108_CSRT 0x01 -#define CFG_108_MCTL 0x02 - -/* Config registers for the '338 */ -#define CFG_338_FER 0x00 -#define CFG_338_FAR 0x01 -#define CFG_338_PTR 0x02 -#define CFG_338_PNP0 0x1b -#define CFG_338_PNP1 0x1c -#define CFG_338_PNP3 0x4f - -/* Config registers for the '39x (in the logical device bank) */ -#define CFG_39X_LDN 0x07 /* Logical device number (Super I/O bank) */ -#define CFG_39X_SIOCF1 0x21 /* SuperI/O Config */ -#define CFG_39X_ACT 0x30 /* Device activation */ -#define CFG_39X_BASEH 0x60 /* Device base address (high bits) */ -#define CFG_39X_BASEL 0x61 /* Device base address (low bits) */ -#define CFG_39X_IRQNUM 0x70 /* Interrupt number & wake up enable */ -#define CFG_39X_IRQSEL 0x71 /* Interrupt select (edge/level + polarity) */ -#define CFG_39X_DMA0 0x74 /* DMA 0 configuration */ -#define CFG_39X_DMA1 0x75 /* DMA 1 configuration */ -#define CFG_39X_SPC 0xF0 /* Serial port configuration register */ - -/* Flags for configuration register CRF0 */ -#define APEDCRC 0x02 -#define ENBNKSEL 0x01 - -/* Set 0 */ -#define TXD 0x00 /* Transmit data port */ -#define RXD 0x00 /* Receive data port */ - -/* Register 1 */ -#define IER 0x01 /* Interrupt Enable Register*/ -#define IER_RXHDL_IE 0x01 /* Receiver high data level interrupt */ -#define IER_TXLDL_IE 0x02 /* Transeiver low data level interrupt */ -#define IER_LS_IE 0x04//* Link Status Interrupt */ -#define IER_ETXURI 0x04 /* Tx underrun */ -#define IER_DMA_IE 0x10 /* DMA finished interrupt */ -#define IER_TXEMP_IE 0x20 -#define IER_SFIF_IE 0x40 /* Frame status FIFO intr */ -#define IER_TMR_IE 0x80 /* Timer event */ - -#define FCR 0x02 /* (write only) */ -#define FCR_FIFO_EN 0x01 /* Enable FIFO's */ -#define FCR_RXSR 0x02 /* Rx FIFO soft reset */ -#define FCR_TXSR 0x04 /* Tx FIFO soft reset */ -#define FCR_RXTH 0x40 /* Rx FIFO threshold (set to 16) */ -#define FCR_TXTH 0x20 /* Tx FIFO threshold (set to 17) */ - -#define EIR 0x02 /* (read only) */ -#define EIR_RXHDL_EV 0x01 -#define EIR_TXLDL_EV 0x02 -#define EIR_LS_EV 0x04 -#define EIR_DMA_EV 0x10 -#define EIR_TXEMP_EV 0x20 -#define EIR_SFIF_EV 0x40 -#define EIR_TMR_EV 0x80 - -#define LCR 0x03 /* Link control register */ -#define LCR_WLS_8 0x03 /* 8 bits */ - -#define BSR 0x03 /* Bank select register */ -#define BSR_BKSE 0x80 -#define BANK0 LCR_WLS_8 /* Must make sure that we set 8N1 */ -#define BANK1 0x80 -#define BANK2 0xe0 -#define BANK3 0xe4 -#define BANK4 0xe8 -#define BANK5 0xec -#define BANK6 0xf0 -#define BANK7 0xf4 - -#define MCR 0x04 /* Mode Control Register */ -#define MCR_MODE_MASK ~(0xd0) -#define MCR_UART 0x00 -#define MCR_RESERVED 0x20 -#define MCR_SHARP_IR 0x40 -#define MCR_SIR 0x60 -#define MCR_MIR 0x80 -#define MCR_FIR 0xa0 -#define MCR_CEIR 0xb0 -#define MCR_IR_PLS 0x10 -#define MCR_DMA_EN 0x04 -#define MCR_EN_IRQ 0x08 -#define MCR_TX_DFR 0x08 - -#define LSR 0x05 /* Link status register */ -#define LSR_RXDA 0x01 /* Receiver data available */ -#define LSR_TXRDY 0x20 /* Transmitter ready */ -#define LSR_TXEMP 0x40 /* Transmitter empty */ - -#define ASCR 0x07 /* Auxillary Status and Control Register */ -#define ASCR_RXF_TOUT 0x01 /* Rx FIFO timeout */ -#define ASCR_FEND_INF 0x02 /* Frame end bytes in rx FIFO */ -#define ASCR_S_EOT 0x04 /* Set end of transmission */ -#define ASCT_RXBSY 0x20 /* Rx busy */ -#define ASCR_TXUR 0x40 /* Transeiver underrun */ -#define ASCR_CTE 0x80 /* Clear timer event */ - -/* Bank 2 */ -#define BGDL 0x00 /* Baud Generator Divisor Port (Low Byte) */ -#define BGDH 0x01 /* Baud Generator Divisor Port (High Byte) */ - -#define ECR1 0x02 /* Extended Control Register 1 */ -#define ECR1_EXT_SL 0x01 /* Extended Mode Select */ -#define ECR1_DMANF 0x02 /* DMA Fairness */ -#define ECR1_DMATH 0x04 /* DMA Threshold */ -#define ECR1_DMASWP 0x08 /* DMA Swap */ - -#define EXCR2 0x04 -#define EXCR2_TFSIZ 0x01 /* Rx FIFO size = 32 */ -#define EXCR2_RFSIZ 0x04 /* Tx FIFO size = 32 */ - -#define TXFLV 0x06 /* Tx FIFO level */ -#define RXFLV 0x07 /* Rx FIFO level */ - -/* Bank 3 */ -#define MID 0x00 - -/* Bank 4 */ -#define TMRL 0x00 /* Timer low byte */ -#define TMRH 0x01 /* Timer high byte */ -#define IRCR1 0x02 /* Infrared control register 1 */ -#define IRCR1_TMR_EN 0x01 /* Timer enable */ - -#define TFRLL 0x04 -#define TFRLH 0x05 -#define RFRLL 0x06 -#define RFRLH 0x07 - -/* Bank 5 */ -#define IRCR2 0x04 /* Infrared control register 2 */ -#define IRCR2_MDRS 0x04 /* MIR data rate select */ -#define IRCR2_FEND_MD 0x20 /* */ - -#define FRM_ST 0x05 /* Frame status FIFO */ -#define FRM_ST_VLD 0x80 /* Frame status FIFO data valid */ -#define FRM_ST_ERR_MSK 0x5f -#define FRM_ST_LOST_FR 0x40 /* Frame lost */ -#define FRM_ST_MAX_LEN 0x10 /* Max frame len exceeded */ -#define FRM_ST_PHY_ERR 0x08 /* Physical layer error */ -#define FRM_ST_BAD_CRC 0x04 -#define FRM_ST_OVR1 0x02 /* Rx FIFO overrun */ -#define FRM_ST_OVR2 0x01 /* Frame status FIFO overrun */ - -#define RFLFL 0x06 -#define RFLFH 0x07 - -/* Bank 6 */ -#define IR_CFG2 0x00 -#define IR_CFG2_DIS_CRC 0x02 - -/* Bank 7 */ -#define IRM_CR 0x07 /* Infrared module control register */ -#define IRM_CR_IRX_MSL 0x40 -#define IRM_CR_AF_MNT 0x80 /* Automatic format */ - -/* NSC chip information */ -struct nsc_chip { - char *name; /* Name of chipset */ - int cfg[3]; /* Config registers */ - u_int8_t cid_index; /* Chip identification index reg */ - u_int8_t cid_value; /* Chip identification expected value */ - u_int8_t cid_mask; /* Chip identification revision mask */ - - /* Functions for probing and initializing the specific chip */ - int (*probe)(struct nsc_chip *chip, chipio_t *info); - int (*init)(struct nsc_chip *chip, chipio_t *info); -}; -typedef struct nsc_chip nsc_chip_t; - -/* For storing entries in the status FIFO */ -struct st_fifo_entry { - int status; - int len; -}; - -#define MAX_TX_WINDOW 7 -#define MAX_RX_WINDOW 7 - -struct st_fifo { - struct st_fifo_entry entries[MAX_RX_WINDOW]; - int pending_bytes; - int head; - int tail; - int len; -}; - -struct frame_cb { - void *start; /* Start of frame in DMA mem */ - int len; /* Lenght of frame in DMA mem */ -}; - -struct tx_fifo { - struct frame_cb queue[MAX_TX_WINDOW]; /* Info about frames in queue */ - int ptr; /* Currently being sent */ - int len; /* Lenght of queue */ - int free; /* Next free slot */ - void *tail; /* Next free start in DMA mem */ -}; - -/* Private data for each instance */ -struct nsc_ircc_cb { - struct st_fifo st_fifo; /* Info about received frames */ - struct tx_fifo tx_fifo; /* Info about frames to be transmitted */ - - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are binded to */ - struct qos_info qos; /* QoS capabilities for this device */ - - chipio_t io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - __u8 ier; /* Interrupt enable register */ - - struct timeval stamp; - struct timeval now; - - spinlock_t lock; /* For serializing operations */ - - __u32 new_speed; - int index; /* Instance index */ - - struct pm_dev *dev; -}; - -static inline void switch_bank(int iobase, int bank) -{ - outb(bank, iobase+BSR); -} - -#endif /* NSC_IRCC_H */ diff -Nru a/include/net/irda/smc-ircc.h b/include/net/irda/smc-ircc.h --- a/include/net/irda/smc-ircc.h Sun Apr 18 13:42:40 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,180 +0,0 @@ -/********************************************************************* - * - * Filename: smc-ircc.h - * Version: 0.3 - * Description: Definitions for the SMC IrCC chipset - * Status: Experimental. - * Author: Thomas Davis (tadavis@jps.net) - * - * Copyright (c) 1999-2000, Dag Brattli - * Copyright (c) 1998-1999, Thomas Davis (tadavis@jps.net> - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -#ifndef SMC_IRCC_H -#define SMC_IRCC_H - -#include -#include - -#include - -/* DMA modes needed */ -#define DMA_TX_MODE 0x08 /* Mem to I/O, ++, demand. */ -#define DMA_RX_MODE 0x04 /* I/O to mem, ++, demand. */ - -/* Master Control Register */ -#define IRCC_MASTER 0x07 -#define IRCC_MASTER_POWERDOWN 0x80 -#define IRCC_MASTER_RESET 0x40 -#define IRCC_MASTER_INT_EN 0x20 -#define IRCC_MASTER_ERROR_RESET 0x10 - -/* Register block 0 */ - -/* Interrupt Identification */ -#define IRCC_IIR 0x01 -#define IRCC_IIR_ACTIVE_FRAME 0x80 -#define IRCC_IIR_EOM 0x40 -#define IRCC_IIR_RAW_MODE 0x20 -#define IRCC_IIR_FIFO 0x10 - -/* Interrupt Enable */ -#define IRCC_IER 0x02 -#define IRCC_IER_ACTIVE_FRAME 0x80 -#define IRCC_IER_EOM 0x40 -#define IRCC_IER_RAW_MODE 0x20 -#define IRCC_IER_FIFO 0x10 - -/* Line Status Register */ -#define IRCC_LSR 0x03 -#define IRCC_LSR_UNDERRUN 0x80 -#define IRCC_LSR_OVERRUN 0x40 -#define IRCC_LSR_FRAME_ERROR 0x20 -#define IRCC_LSR_SIZE_ERROR 0x10 -#define IRCC_LSR_CRC_ERROR 0x80 -#define IRCC_LSR_FRAME_ABORT 0x40 - -/* Line Control Register A */ -#define IRCC_LCR_A 0x04 -#define IRCC_LCR_A_FIFO_RESET 0x80 -#define IRCC_LCR_A_FAST 0x40 -#define IRCC_LCR_A_GP_DATA 0x20 -#define IRCC_LCR_A_RAW_TX 0x10 -#define IRCC_LCR_A_RAW_RX 0x08 -#define IRCC_LCR_A_ABORT 0x04 -#define IRCC_LCR_A_DATA_DONE 0x02 - -/* Line Control Register B */ -#define IRCC_LCR_B 0x05 -#define IRCC_LCR_B_SCE_DISABLED 0x00 -#define IRCC_LCR_B_SCE_TRANSMIT 0x40 -#define IRCC_LCR_B_SCE_RECEIVE 0x80 -#define IRCC_LCR_B_SCE_UNDEFINED 0xc0 -#define IRCC_LCR_B_SIP_ENABLE 0x20 -#define IRCC_LCR_B_BRICK_WALL 0x10 - -/* Bus Status Register */ -#define IRCC_BSR 0x06 -#define IRCC_BSR_NOT_EMPTY 0x80 -#define IRCC_BSR_FIFO_FULL 0x40 -#define IRCC_BSR_TIMEOUT 0x20 - -/* Register block 1 */ - -#define IRCC_FIFO_THRESHOLD 0x02 - -#define IRCC_SCE_CFGA 0x00 -#define IRCC_CFGA_AUX_IR 0x80 -#define IRCC_CFGA_HALF_DUPLEX 0x04 -#define IRCC_CFGA_TX_POLARITY 0x02 -#define IRCC_CFGA_RX_POLARITY 0x01 - -#define IRCC_CFGA_COM 0x00 -#define IRCC_CFGA_IRDA_SIR_A 0x08 -#define IRCC_CFGA_ASK_SIR 0x10 -#define IRCC_CFGA_IRDA_SIR_B 0x18 -#define IRCC_CFGA_IRDA_HDLC 0x20 -#define IRCC_CFGA_IRDA_4PPM 0x28 -#define IRCC_CFGA_CONSUMER 0x30 -#define IRCC_CFGA_RAW_IR 0x38 -#define IRCC_CFGA_OTHER 0x40 - -#define IRCC_IR_HDLC 0x04 -#define IRCC_IR_4PPM 0x01 -#define IRCC_IR_CONSUMER 0x02 - -#define IRCC_SCE_CFGB 0x01 -#define IRCC_CFGB_LOOPBACK 0x20 -#define IRCC_CFGB_LPBCK_TX_CRC 0x10 -#define IRCC_CFGB_NOWAIT 0x08 -#define IRCC_CFGB_STRING_MOVE 0x04 -#define IRCC_CFGB_DMA_BURST 0x02 -#define IRCC_CFGB_DMA_ENABLE 0x01 - -#define IRCC_CFGB_MUX_COM 0x00 -#define IRCC_CFGB_MUX_IR 0x40 -#define IRCC_CFGB_MUX_AUX 0x80 -#define IRCC_CFGB_MUX_INACTIVE 0xc0 - -/* Register block 3 - Identification Registers! */ -#define IRCC_ID_HIGH 0x00 /* 0x10 */ -#define IRCC_ID_LOW 0x01 /* 0xB8 */ -#define IRCC_CHIP_ID 0x02 /* 0xF1 */ -#define IRCC_VERSION 0x03 /* 0x01 */ -#define IRCC_INTERFACE 0x04 /* low 4 = DMA, high 4 = IRQ */ - -/* Register block 4 - IrDA */ -#define IRCC_CONTROL 0x00 -#define IRCC_BOF_COUNT_LO 0x01 /* Low byte */ -#define IRCC_BOF_COUNT_HI 0x00 /* High nibble (bit 0-3) */ -#define IRCC_BRICKWALL_CNT_LO 0x02 /* Low byte */ -#define IRCC_BRICKWALL_CNT_HI 0x03 /* High nibble (bit 4-7) */ -#define IRCC_TX_SIZE_LO 0x04 /* Low byte */ -#define IRCC_TX_SIZE_HI 0x03 /* High nibble (bit 0-3) */ -#define IRCC_RX_SIZE_HI 0x05 /* High nibble (bit 0-3) */ -#define IRCC_RX_SIZE_LO 0x06 /* Low byte */ - -#define IRCC_1152 0x80 -#define IRCC_CRC 0x40 - -/* Private data for each instance */ -struct ircc_cb { - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct irlap_cb *irlap; /* The link layer we are binded to */ - - chipio_t *io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - struct irport_cb *irport; - - /* Locking : half of our operations are done with irport, so we - * use the irport spinlock to make sure *everything* is properly - * synchronised - Jean II */ - - __u32 new_speed; - - int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ - int tx_len; /* Number of frames in tx_buff */ - - struct pm_dev *pmdev; -}; - -#endif /* SMC_IRCC_H */ diff -Nru a/include/net/irda/toshoboe.h b/include/net/irda/toshoboe.h --- a/include/net/irda/toshoboe.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,166 +0,0 @@ -/********************************************************************* - * - * Filename: toshoboe.h - * Version: 0.1 - * Description: Driver for the Toshiba OBOE (or type-O) - * FIR Chipset. - * Status: Experimental. - * Author: James McKenzie - * Created at: Sat May 8 12:35:27 1999 - * - * Copyright (c) 1999-2000 James McKenzie, All Rights Reserved. - * - * 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. - * - * Neither James McKenzie nor Cambridge University admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - * Applicable Models : Libretto 100CT. and many more - * - ********************************************************************/ - -#ifndef TOSHOBOE_H -#define TOSHOBOE_H - -/* Registers */ -/*Receive and transmit task registers (read only) */ -#define OBOE_RCVT (0x00+(self->base)) -#define OBOE_XMTT (0x01+(self->base)) -#define OBOE_XMTT_OFFSET 0x40 - -/*Page pointers to the TaskFile structure */ -#define OBOE_TFP2 (0x02+(self->base)) -#define OBOE_TFP0 (0x04+(self->base)) -#define OBOE_TFP1 (0x05+(self->base)) - -/*Dunno */ -#define OBOE_REG_3 (0x03+(self->base)) - -/*Number of tasks to use in Xmit and Recv queues */ -#define OBOE_NTR (0x07+(self->base)) -#define OBOE_NTR_XMIT4 0x00 -#define OBOE_NTR_XMIT8 0x10 -#define OBOE_NTR_XMIT16 0x30 -#define OBOE_NTR_XMIT32 0x70 -#define OBOE_NTR_XMIT64 0xf0 -#define OBOE_NTR_RECV4 0x00 -#define OBOE_NTR_RECV8 0x01 -#define OBOE_NTR_RECV6 0x03 -#define OBOE_NTR_RECV32 0x07 -#define OBOE_NTR_RECV64 0x0f - -/* Dunno */ -#define OBOE_REG_9 (0x09+(self->base)) - -/* Interrupt Status Register */ -#define OBOE_ISR (0x0c+(self->base)) -#define OBOE_ISR_TXDONE 0x80 -#define OBOE_ISR_RXDONE 0x40 -#define OBOE_ISR_20 0x20 -#define OBOE_ISR_10 0x10 -#define OBOE_ISR_8 0x08 /*This is collision or parity or something */ -#define OBOE_ISR_4 0x08 -#define OBOE_ISR_2 0x08 -#define OBOE_ISR_1 0x08 - -/*Dunno */ -#define OBOE_REG_D (0x0d+(self->base)) - -/*Register Lock Register */ -#define OBOE_LOCK ((self->base)+0x0e) - - - -/*Speed control registers */ -#define OBOE_PMDL (0x10+(self->base)) -#define OBOE_PMDL_SIR 0x18 -#define OBOE_PMDL_MIR 0xa0 -#define OBOE_PMDL_FIR 0x40 - -#define OBOE_SMDL (0x18+(self->base)) -#define OBOE_SMDL_SIR 0x20 -#define OBOE_SMDL_MIR 0x01 -#define OBOE_SMDL_FIR 0x0f - -#define OBOE_UDIV (0x19+(self->base)) - -/*Dunno */ -#define OBOE_REG_11 (0x11+(self->base)) - -/*Chip Reset Register */ -#define OBOE_RST (0x15+(self->base)) -#define OBOE_RST_WRAP 0x8 - -/*Dunno */ -#define OBOE_REG_1A (0x1a+(self->base)) -#define OBOE_REG_1B (0x1b+(self->base)) - -/* The PCI ID of the OBOE chip */ -#ifndef PCI_DEVICE_ID_FIR701 -#define PCI_DEVICE_ID_FIR701 0x0701 -#endif - -typedef unsigned int dword; -typedef unsigned short int word; -typedef unsigned char byte; -typedef dword Paddr; - -struct OboeTask - { - __u16 len; - __u8 unused; - __u8 control; - __u32 buffer; - }; - -#define OBOE_NTASKS 64 - -struct OboeTaskFile - { - struct OboeTask recv[OBOE_NTASKS]; - struct OboeTask xmit[OBOE_NTASKS]; - }; - -#define OBOE_TASK_BUF_LEN (sizeof(struct OboeTaskFile) << 1) - -/*These set the number of slots in use */ -#define TX_SLOTS 4 -#define RX_SLOTS 4 - -/* You need also to change this, toshiba uses 4,8 and 4,4 */ -/* It makes no difference if you are only going to use ONETASK mode */ -/* remember each buffer use XX_BUF_SZ more _PHYSICAL_ memory */ -#define OBOE_NTR_VAL (OBOE_NTR_XMIT4 | OBOE_NTR_RECV4) - -struct toshoboe_cb - { - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are binded to */ - struct qos_info qos; /* QoS capabilities for this device */ - - chipio_t io; /* IrDA controller information */ - - __u32 new_speed; - - struct pci_dev *pdev; /*PCI device */ - int base; /*IO base */ - int txpending; /*how many tx's are pending */ - int txs, rxs; /*Which slots are we at */ - void *taskfilebuf; /*The unaligned taskfile buffer */ - struct OboeTaskFile *taskfile; /*The taskfile */ - void *xmit_bufs[TX_SLOTS]; /*The buffers */ - void *recv_bufs[RX_SLOTS]; - int open; - int stopped; /*Stopped by some or other APM stuff*/ - }; - - -#endif - - diff -Nru a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h --- a/include/net/irda/vlsi_ir.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,799 +0,0 @@ - -/********************************************************************* - * - * vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux - * - * Version: 0.5 - * - * Copyright (c) 2001-2003 Martin Diehl - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ********************************************************************/ - -#ifndef IRDA_VLSI_FIR_H -#define IRDA_VLSI_FIR_H - -/* ================================================================ - * compatibility stuff - */ - -/* definitions not present in pci_ids.h */ - -#ifndef PCI_CLASS_WIRELESS_IRDA -#define PCI_CLASS_WIRELESS_IRDA 0x0d00 -#endif - -#ifndef PCI_CLASS_SUBCLASS_MASK -#define PCI_CLASS_SUBCLASS_MASK 0xffff -#endif - -/* in recent 2.5 interrupt handlers have non-void return value */ -#ifndef IRQ_RETVAL -typedef void irqreturn_t; -#define IRQ_NONE -#define IRQ_HANDLED -#define IRQ_RETVAL(x) -#endif - -/* some stuff need to check kernelversion. Not all 2.5 stuff was present - * in early 2.5.x - the test is merely to separate 2.4 from 2.5 - */ -#include - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - -/* PDE() introduced in 2.5.4 */ -#ifdef CONFIG_PROC_FS -#define PDE(inode) ((inode)->u.generic_ip) -#endif - -/* irda crc16 calculation exported in 2.5.42 */ -#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS) - -/* we use this for unified pci device name access */ -#define PCIDEV_NAME(pdev) ((pdev)->name) - -#else /* 2.5 or later */ - -/* recent 2.5/2.6 stores pci device names at varying places ;-) */ -#ifdef CONFIG_PCI_NAMES -/* human readable name */ -#define PCIDEV_NAME(pdev) ((pdev)->pretty_name) -#else -/* whatever we get from the associated struct device - bus:slot:dev.fn id */ -#define PCIDEV_NAME(pdev) (pci_name(pdev)) -#endif - -#endif - -/* ================================================================ */ - -/* non-standard PCI registers */ - -enum vlsi_pci_regs { - VLSI_PCI_CLKCTL = 0x40, /* chip clock input control */ - VLSI_PCI_MSTRPAGE = 0x41, /* addr [31:24] for all busmaster cycles */ - VLSI_PCI_IRMISC = 0x42 /* mainly legacy UART related */ -}; - -/* ------------------------------------------ */ - -/* VLSI_PCI_CLKCTL: Clock Control Register (u8, rw) */ - -/* Three possible clock sources: either on-chip 48MHz PLL or - * external clock applied to EXTCLK pin. External clock may - * be either 48MHz or 40MHz, which is indicated by XCKSEL. - * CLKSTP controls whether the selected clock source gets - * connected to the IrDA block. - * - * On my HP OB-800 the BIOS sets external 40MHz clock as source - * when IrDA enabled and I've never detected any PLL lock success. - * Apparently the 14.3...MHz OSC input required for the PLL to work - * is not connected and the 40MHz EXTCLK is provided externally. - * At least this is what makes the driver working for me. - */ - -enum vlsi_pci_clkctl { - - /* PLL control */ - - CLKCTL_PD_INV = 0x04, /* PD#: inverted power down signal, - * i.e. PLL is powered, if PD_INV set */ - CLKCTL_LOCK = 0x40, /* (ro) set, if PLL is locked */ - - /* clock source selection */ - - CLKCTL_EXTCLK = 0x20, /* set to select external clock input, not PLL */ - CLKCTL_XCKSEL = 0x10, /* set to indicate EXTCLK is 40MHz, not 48MHz */ - - /* IrDA block control */ - - CLKCTL_CLKSTP = 0x80, /* set to disconnect from selected clock source */ - CLKCTL_WAKE = 0x08 /* set to enable wakeup feature: whenever IR activity - * is detected, PD_INV gets set(?) and CLKSTP cleared */ -}; - -/* ------------------------------------------ */ - -/* VLSI_PCI_MSTRPAGE: Master Page Register (u8, rw) and busmastering stuff */ - -#define DMA_MASK_USED_BY_HW 0xffffffff -#define DMA_MASK_MSTRPAGE 0x00ffffff -#define MSTRPAGE_VALUE (DMA_MASK_MSTRPAGE >> 24) - - /* PCI busmastering is somewhat special for this guy - in short: - * - * We select to operate using fixed MSTRPAGE=0, use ISA DMA - * address restrictions to make the PCI BM api aware of this, - * but ensure the hardware is dealing with real 32bit access. - * - * In detail: - * The chip executes normal 32bit busmaster cycles, i.e. - * drives all 32 address lines. These addresses however are - * composed of [0:23] taken from various busaddr-pointers - * and [24:31] taken from the MSTRPAGE register in the VLSI82C147 - * config space. Therefore _all_ busmastering must be - * targeted to/from one single 16MB (busaddr-) superpage! - * The point is to make sure all the allocations for memory - * locations with busmaster access (ring descriptors, buffers) - * are indeed bus-mappable to the same 16MB range (for x86 this - * means they must reside in the same 16MB physical memory address - * range). The only constraint we have which supports "several objects - * mappable to common 16MB range" paradigma, is the old ISA DMA - * restriction to the first 16MB of physical address range. - * Hence the approach here is to enable PCI busmaster support using - * the correct 32bit dma-mask used by the chip. Afterwards the device's - * dma-mask gets restricted to 24bit, which must be honoured somehow by - * all allocations for memory areas to be exposed to the chip ... - * - * Note: - * Don't be surprised to get "Setting latency timer..." messages every - * time when PCI busmastering is enabled for the chip. - * The chip has its PCI latency timer RO fixed at 0 - which is not a - * problem here, because it is never requesting _burst_ transactions. - */ - -/* ------------------------------------------ */ - -/* VLSI_PCIIRMISC: IR Miscellaneous Register (u8, rw) */ - -/* legacy UART emulation - not used by this driver - would require: - * (see below for some register-value definitions) - * - * - IRMISC_UARTEN must be set to enable UART address decoding - * - IRMISC_UARTSEL configured - * - IRCFG_MASTER must be cleared - * - IRCFG_SIR must be set - * - IRENABLE_PHYANDCLOCK must be asserted 0->1 (and hence IRENABLE_SIR_ON) - */ - -enum vlsi_pci_irmisc { - - /* IR transceiver control */ - - IRMISC_IRRAIL = 0x40, /* (ro?) IR rail power indication (and control?) - * 0=3.3V / 1=5V. Probably set during power-on? - * unclear - not touched by driver */ - IRMISC_IRPD = 0x08, /* transceiver power down, if set */ - - /* legacy UART control */ - - IRMISC_UARTTST = 0x80, /* UART test mode - "always write 0" */ - IRMISC_UARTEN = 0x04, /* enable UART address decoding */ - - /* bits [1:0] IRMISC_UARTSEL to select legacy UART address */ - - IRMISC_UARTSEL_3f8 = 0x00, - IRMISC_UARTSEL_2f8 = 0x01, - IRMISC_UARTSEL_3e8 = 0x02, - IRMISC_UARTSEL_2e8 = 0x03 -}; - -/* ================================================================ */ - -/* registers mapped to 32 byte PCI IO space */ - -/* note: better access all registers at the indicated u8/u16 size - * although some of them contain only 1 byte of information. - * some of them (particaluarly PROMPT and IRCFG) ignore - * access when using the wrong addressing mode! - */ - -enum vlsi_pio_regs { - VLSI_PIO_IRINTR = 0x00, /* interrupt enable/request (u8, rw) */ - VLSI_PIO_RINGPTR = 0x02, /* rx/tx ring pointer (u16, ro) */ - VLSI_PIO_RINGBASE = 0x04, /* [23:10] of ring address (u16, rw) */ - VLSI_PIO_RINGSIZE = 0x06, /* rx/tx ring size (u16, rw) */ - VLSI_PIO_PROMPT = 0x08, /* triggers ring processing (u16, wo) */ - /* 0x0a-0x0f: reserved / duplicated UART regs */ - VLSI_PIO_IRCFG = 0x10, /* configuration select (u16, rw) */ - VLSI_PIO_SIRFLAG = 0x12, /* BOF/EOF for filtered SIR (u16, ro) */ - VLSI_PIO_IRENABLE = 0x14, /* enable and status register (u16, rw/ro) */ - VLSI_PIO_PHYCTL = 0x16, /* physical layer current status (u16, ro) */ - VLSI_PIO_NPHYCTL = 0x18, /* next physical layer select (u16, rw) */ - VLSI_PIO_MAXPKT = 0x1a, /* [11:0] max len for packet receive (u16, rw) */ - VLSI_PIO_RCVBCNT = 0x1c /* current receive-FIFO byte count (u16, ro) */ - /* 0x1e-0x1f: reserved / duplicated UART regs */ -}; - -/* ------------------------------------------ */ - -/* VLSI_PIO_IRINTR: Interrupt Register (u8, rw) */ - -/* enable-bits: - * 1 = enable / 0 = disable - * interrupt condition bits: - * set according to corresponding interrupt source - * (regardless of the state of the enable bits) - * enable bit status indicates whether interrupt gets raised - * write-to-clear - * note: RPKTINT and TPKTINT behave different in legacy UART mode (which we don't use :-) - */ - -enum vlsi_pio_irintr { - IRINTR_ACTEN = 0x80, /* activity interrupt enable */ - IRINTR_ACTIVITY = 0x40, /* activity monitor (traffic detected) */ - IRINTR_RPKTEN = 0x20, /* receive packet interrupt enable*/ - IRINTR_RPKTINT = 0x10, /* rx-packet transfered from fifo to memory finished */ - IRINTR_TPKTEN = 0x08, /* transmit packet interrupt enable */ - IRINTR_TPKTINT = 0x04, /* last bit of tx-packet+crc shifted to ir-pulser */ - IRINTR_OE_EN = 0x02, /* UART rx fifo overrun error interrupt enable */ - IRINTR_OE_INT = 0x01 /* UART rx fifo overrun error (read LSR to clear) */ -}; - -/* we use this mask to check whether the (shared PCI) interrupt is ours */ - -#define IRINTR_INT_MASK (IRINTR_ACTIVITY|IRINTR_RPKTINT|IRINTR_TPKTINT) - -/* ------------------------------------------ */ - -/* VLSI_PIO_RINGPTR: Ring Pointer Read-Back Register (u16, ro) */ - -/* _both_ ring pointers are indices relative to the _entire_ rx,tx-ring! - * i.e. the referenced descriptor is located - * at RINGBASE + PTR * sizeof(descr) for rx and tx - * therefore, the tx-pointer has offset MAX_RING_DESCR - */ - -#define MAX_RING_DESCR 64 /* tx, rx rings may contain up to 64 descr each */ - -#define RINGPTR_RX_MASK (MAX_RING_DESCR-1) -#define RINGPTR_TX_MASK ((MAX_RING_DESCR-1)<<8) - -#define RINGPTR_GET_RX(p) ((p)&RINGPTR_RX_MASK) -#define RINGPTR_GET_TX(p) (((p)&RINGPTR_TX_MASK)>>8) - -/* ------------------------------------------ */ - -/* VLSI_PIO_RINGBASE: Ring Pointer Base Address Register (u16, ro) */ - -/* Contains [23:10] part of the ring base (bus-) address - * which must be 1k-alinged. [31:24] is taken from - * VLSI_PCI_MSTRPAGE above. - * The controller initiates non-burst PCI BM cycles to - * fetch and update the descriptors in the ring. - * Once fetched, the descriptor remains cached onchip - * until it gets closed and updated due to the ring - * processing state machine. - * The entire ring area is split in rx and tx areas with each - * area consisting of 64 descriptors of 8 bytes each. - * The rx(tx) ring is located at ringbase+0 (ringbase+64*8). - */ - -#define BUS_TO_RINGBASE(p) (((p)>>10)&0x3fff) - -/* ------------------------------------------ */ - -/* VLSI_PIO_RINGSIZE: Ring Size Register (u16, rw) */ - -/* bit mask to indicate the ring size to be used for rx and tx. - * possible values encoded bits - * 4 0000 - * 8 0001 - * 16 0011 - * 32 0111 - * 64 1111 - * located at [15:12] for tx and [11:8] for rx ([7:0] unused) - * - * note: probably a good idea to have IRCFG_MSTR cleared when writing - * this so the state machines are stopped and the RINGPTR is reset! - */ - -#define SIZE_TO_BITS(num) ((((num)-1)>>2)&0x0f) -#define TX_RX_TO_RINGSIZE(tx,rx) ((SIZE_TO_BITS(tx)<<12)|(SIZE_TO_BITS(rx)<<8)) -#define RINGSIZE_TO_RXSIZE(rs) ((((rs)&0x0f00)>>6)+4) -#define RINGSIZE_TO_TXSIZE(rs) ((((rs)&0xf000)>>10)+4) - - -/* ------------------------------------------ */ - -/* VLSI_PIO_PROMPT: Ring Prompting Register (u16, write-to-start) */ - -/* writing any value kicks the ring processing state machines - * for both tx, rx rings as follows: - * - active rings (currently owning an active descriptor) - * ignore the prompt and continue - * - idle rings fetch the next descr from the ring and start - * their processing - */ - -/* ------------------------------------------ */ - -/* VLSI_PIO_IRCFG: IR Config Register (u16, rw) */ - -/* notes: - * - not more than one SIR/MIR/FIR bit must be set at any time - * - SIR, MIR, FIR and CRC16 select the configuration which will - * be applied on next 0->1 transition of IRENABLE_PHYANDCLOCK (see below). - * - besides allowing the PCI interface to execute busmaster cycles - * and therefore the ring SM to operate, the MSTR bit has side-effects: - * when MSTR is cleared, the RINGPTR's get reset and the legacy UART mode - * (in contrast to busmaster access mode) gets enabled. - * - clearing ENRX or setting ENTX while data is received may stall the - * receive fifo until ENRX reenabled _and_ another packet arrives - * - SIRFILT means the chip performs the required unwrapping of hardware - * headers (XBOF's, BOF/EOF) and un-escaping in the _receive_ direction. - * Only the resulting IrLAP payload is copied to the receive buffers - - * but with the 16bit FCS still encluded. Question remains, whether it - * was already checked or we should do it before passing the packet to IrLAP? - */ - -enum vlsi_pio_ircfg { - IRCFG_LOOP = 0x4000, /* enable loopback test mode */ - IRCFG_ENTX = 0x1000, /* transmit enable */ - IRCFG_ENRX = 0x0800, /* receive enable */ - IRCFG_MSTR = 0x0400, /* master enable */ - IRCFG_RXANY = 0x0200, /* receive any packet */ - IRCFG_CRC16 = 0x0080, /* 16bit (not 32bit) CRC select for MIR/FIR */ - IRCFG_FIR = 0x0040, /* FIR 4PPM encoding mode enable */ - IRCFG_MIR = 0x0020, /* MIR HDLC encoding mode enable */ - IRCFG_SIR = 0x0010, /* SIR encoding mode enable */ - IRCFG_SIRFILT = 0x0008, /* enable SIR decode filter (receiver unwrapping) */ - IRCFG_SIRTEST = 0x0004, /* allow SIR decode filter when not in SIR mode */ - IRCFG_TXPOL = 0x0002, /* invert tx polarity when set */ - IRCFG_RXPOL = 0x0001 /* invert rx polarity when set */ -}; - -/* ------------------------------------------ */ - -/* VLSI_PIO_SIRFLAG: SIR Flag Register (u16, ro) */ - -/* register contains hardcoded BOF=0xc0 at [7:0] and EOF=0xc1 at [15:8] - * which is used for unwrapping received frames in SIR decode-filter mode - */ - -/* ------------------------------------------ */ - -/* VLSI_PIO_IRENABLE: IR Enable Register (u16, rw/ro) */ - -/* notes: - * - IREN acts as gate for latching the configured IR mode information - * from IRCFG and IRPHYCTL when IREN=reset and applying them when - * IREN gets set afterwards. - * - ENTXST reflects IRCFG_ENTX - * - ENRXST = IRCFG_ENRX && (!IRCFG_ENTX || IRCFG_LOOP) - */ - -enum vlsi_pio_irenable { - IRENABLE_PHYANDCLOCK = 0x8000, /* enable IR phy and gate the mode config (rw) */ - IRENABLE_CFGER = 0x4000, /* mode configuration error (ro) */ - IRENABLE_FIR_ON = 0x2000, /* FIR on status (ro) */ - IRENABLE_MIR_ON = 0x1000, /* MIR on status (ro) */ - IRENABLE_SIR_ON = 0x0800, /* SIR on status (ro) */ - IRENABLE_ENTXST = 0x0400, /* transmit enable status (ro) */ - IRENABLE_ENRXST = 0x0200, /* Receive enable status (ro) */ - IRENABLE_CRC16_ON = 0x0100 /* 16bit (not 32bit) CRC enabled status (ro) */ -}; - -#define IRENABLE_MASK 0xff00 /* Read mask */ - -/* ------------------------------------------ */ - -/* VLSI_PIO_PHYCTL: IR Physical Layer Current Control Register (u16, ro) */ - -/* read-back of the currently applied physical layer status. - * applied from VLSI_PIO_NPHYCTL at rising edge of IRENABLE_PHYANDCLOCK - * contents identical to VLSI_PIO_NPHYCTL (see below) - */ - -/* ------------------------------------------ */ - -/* VLSI_PIO_NPHYCTL: IR Physical Layer Next Control Register (u16, rw) */ - -/* latched during IRENABLE_PHYANDCLOCK=0 and applied at 0-1 transition - * - * consists of BAUD[15:10], PLSWID[9:5] and PREAMB[4:0] bits defined as follows: - * - * SIR-mode: BAUD = (115.2kHz / baudrate) - 1 - * PLSWID = (pulsetime * freq / (BAUD+1)) - 1 - * where pulsetime is the requested IrPHY pulse width - * and freq is 8(16)MHz for 40(48)MHz primary input clock - * PREAMB: don't care for SIR - * - * The nominal SIR pulse width is 3/16 bit time so we have PLSWID=12 - * fixed for all SIR speeds at 40MHz input clock (PLSWID=24 at 48MHz). - * IrPHY also allows shorter pulses down to the nominal pulse duration - * at 115.2kbaud (minus some tolerance) which is 1.41 usec. - * Using the expression PLSWID = 12/(BAUD+1)-1 (multiplied by two for 48MHz) - * we get the minimum acceptable PLSWID values according to the VLSI - * specification, which provides 1.5 usec pulse width for all speeds (except - * for 2.4kbaud getting 6usec). This is fine with IrPHY v1.3 specs and - * reduces the transceiver power which drains the battery. At 9.6kbaud for - * example this amounts to more than 90% battery power saving! - * - * MIR-mode: BAUD = 0 - * PLSWID = 9(10) for 40(48) MHz input clock - * to get nominal MIR pulse width - * PREAMB = 1 - * - * FIR-mode: BAUD = 0 - * PLSWID: don't care - * PREAMB = 15 - */ - -#define PHYCTL_BAUD_SHIFT 10 -#define PHYCTL_BAUD_MASK 0xfc00 -#define PHYCTL_PLSWID_SHIFT 5 -#define PHYCTL_PLSWID_MASK 0x03e0 -#define PHYCTL_PREAMB_SHIFT 0 -#define PHYCTL_PREAMB_MASK 0x001f - -#define PHYCTL_TO_BAUD(bwp) (((bwp)&PHYCTL_BAUD_MASK)>>PHYCTL_BAUD_SHIFT) -#define PHYCTL_TO_PLSWID(bwp) (((bwp)&PHYCTL_PLSWID_MASK)>>PHYCTL_PLSWID_SHIFT) -#define PHYCTL_TO_PREAMB(bwp) (((bwp)&PHYCTL_PREAMB_MASK)>>PHYCTL_PREAMB_SHIFT) - -#define BWP_TO_PHYCTL(b,w,p) ((((b)<0) ? (tmp-1) : 0; -} - -#define PHYCTL_SIR(br,ws,cs) BWP_TO_PHYCTL(BAUD_BITS(br),calc_width_bits((br),(ws),(cs)),0) -#define PHYCTL_MIR(cs) BWP_TO_PHYCTL(0,((cs)?9:10),1) -#define PHYCTL_FIR BWP_TO_PHYCTL(0,0,15) - -/* quite ugly, I know. But implementing these calculations here avoids - * having magic numbers in the code and allows some playing with pulsewidths - * without risk to violate the standards. - * FWIW, here is the table for reference: - * - * baudrate BAUD min-PLSWID nom-PLSWID PREAMB - * 2400 47 0(0) 12(24) 0 - * 9600 11 0(0) 12(24) 0 - * 19200 5 1(2) 12(24) 0 - * 38400 2 3(6) 12(24) 0 - * 57600 1 5(10) 12(24) 0 - * 115200 0 11(22) 12(24) 0 - * MIR 0 - 9(10) 1 - * FIR 0 - 0 15 - * - * note: x(y) means x-value for 40MHz / y-value for 48MHz primary input clock - */ - -/* ------------------------------------------ */ - - -/* VLSI_PIO_MAXPKT: Maximum Packet Length register (u16, rw) */ - -/* maximum acceptable length for received packets */ - -/* hw imposed limitation - register uses only [11:0] */ -#define MAX_PACKET_LENGTH 0x0fff - -/* IrLAP I-field (apparently not defined elsewhere) */ -#define IRDA_MTU 2048 - -/* complete packet consists of A(1)+C(1)+I(<=IRDA_MTU) */ -#define IRLAP_SKB_ALLOCSIZE (1+1+IRDA_MTU) - -/* the buffers we use to exchange frames with the hardware need to be - * larger than IRLAP_SKB_ALLOCSIZE because we may have up to 4 bytes FCS - * appended and, in SIR mode, a lot of frame wrapping bytes. The worst - * case appears to be a SIR packet with I-size==IRDA_MTU and all bytes - * requiring to be escaped to provide transparency. Furthermore, the peer - * might ask for quite a number of additional XBOFs: - * up to 115+48 XBOFS 163 - * regular BOF 1 - * A-field 1 - * C-field 1 - * I-field, IRDA_MTU, all escaped 4096 - * FCS (16 bit at SIR, escaped) 4 - * EOF 1 - * AFAICS nothing in IrLAP guarantees A/C field not to need escaping - * (f.e. 0xc0/0xc1 - i.e. BOF/EOF - are legal values there) so in the - * worst case we have 4269 bytes total frame size. - * However, the VLSI uses 12 bits only for all buffer length values, - * which limits the maximum useable buffer size <= 4095. - * Note this is not a limitation in the receive case because we use - * the SIR filtering mode where the hw unwraps the frame and only the - * bare packet+fcs is stored into the buffer - in contrast to the SIR - * tx case where we have to pass frame-wrapped packets to the hw. - * If this would ever become an issue in real life, the only workaround - * I see would be using the legacy UART emulation in SIR mode. - */ - -#define XFER_BUF_SIZE MAX_PACKET_LENGTH - -/* ------------------------------------------ */ - -/* VLSI_PIO_RCVBCNT: Receive Byte Count Register (u16, ro) */ - -/* receive packet counter gets incremented on every non-filtered - * byte which was put in the receive fifo and reset for each - * new packet. Used to decide whether we are just in the middle - * of receiving - */ - -/* better apply the [11:0] mask when reading, as some docs say the - * reserved [15:12] would return 1 when reading - which is wrong AFAICS - */ -#define RCVBCNT_MASK 0x0fff - -/******************************************************************/ - -/* descriptors for rx/tx ring - * - * accessed by hardware - don't change! - * - * the descriptor is owned by hardware, when the ACTIVE status bit - * is set and nothing (besides reading status to test the bit) - * shall be done. The bit gets cleared by hw, when the descriptor - * gets closed. Premature reaping of descriptors owned be the chip - * can be achieved by disabling IRCFG_MSTR - * - * Attention: Writing addr overwrites status! - * - * ### FIXME: depends on endianess (but there ain't no non-i586 ob800 ;-) - */ - -struct ring_descr_hw { - volatile u16 rd_count; /* tx/rx count [11:0] */ - u16 reserved; - union { - u32 addr; /* [23:0] of the buffer's busaddress */ - struct { - u8 addr_res[3]; - volatile u8 status; /* descriptor status */ - } rd_s __attribute__((packed)); - } rd_u __attribute((packed)); -} __attribute__ ((packed)); - -#define rd_addr rd_u.addr -#define rd_status rd_u.rd_s.status - -/* ring descriptor status bits */ - -#define RD_ACTIVE 0x80 /* descriptor owned by hw (both TX,RX) */ - -/* TX ring descriptor status */ - -#define RD_TX_DISCRC 0x40 /* do not send CRC (for SIR) */ -#define RD_TX_BADCRC 0x20 /* force a bad CRC */ -#define RD_TX_PULSE 0x10 /* send indication pulse after this frame (MIR/FIR) */ -#define RD_TX_FRCEUND 0x08 /* force underrun */ -#define RD_TX_CLRENTX 0x04 /* clear ENTX after this frame */ -#define RD_TX_UNDRN 0x01 /* TX fifo underrun (probably PCI problem) */ - -/* RX ring descriptor status */ - -#define RD_RX_PHYERR 0x40 /* physical encoding error */ -#define RD_RX_CRCERR 0x20 /* CRC error (MIR/FIR) */ -#define RD_RX_LENGTH 0x10 /* frame exceeds buffer length */ -#define RD_RX_OVER 0x08 /* RX fifo overrun (probably PCI problem) */ -#define RD_RX_SIRBAD 0x04 /* EOF missing: BOF follows BOF (SIR, filtered) */ - -#define RD_RX_ERROR 0x7c /* any error in received frame */ - -/* the memory required to hold the 2 descriptor rings */ -#define HW_RING_AREA_SIZE (2 * MAX_RING_DESCR * sizeof(struct ring_descr_hw)) - -/******************************************************************/ - -/* sw-ring descriptors consists of a bus-mapped transfer buffer with - * associated skb and a pointer to the hw entry descriptor - */ - -struct ring_descr { - struct ring_descr_hw *hw; - struct sk_buff *skb; - void *buf; -}; - -/* wrappers for operations on hw-exposed ring descriptors - * access to the hw-part of the descriptors must use these. - */ - -static inline int rd_is_active(struct ring_descr *rd) -{ - return ((rd->hw->rd_status & RD_ACTIVE) != 0); -} - -static inline void rd_activate(struct ring_descr *rd) -{ - rd->hw->rd_status |= RD_ACTIVE; -} - -static inline void rd_set_status(struct ring_descr *rd, u8 s) -{ - rd->hw->rd_status = s; /* may pass ownership to the hardware */ -} - -static inline void rd_set_addr_status(struct ring_descr *rd, dma_addr_t a, u8 s) -{ - /* order is important for two reasons: - * - overlayed: writing addr overwrites status - * - we want to write status last so we have valid address in - * case status has RD_ACTIVE set - */ - - if ((a & ~DMA_MASK_MSTRPAGE)>>24 != MSTRPAGE_VALUE) { - ERROR("%s: pci busaddr inconsistency!\n", __FUNCTION__); - dump_stack(); - return; - } - - a &= DMA_MASK_MSTRPAGE; /* clear highbyte to make sure we won't write - * to status - just in case MSTRPAGE_VALUE!=0 - */ - rd->hw->rd_addr = cpu_to_le32(a); - wmb(); - rd_set_status(rd, s); /* may pass ownership to the hardware */ -} - -static inline void rd_set_count(struct ring_descr *rd, u16 c) -{ - rd->hw->rd_count = cpu_to_le16(c); -} - -static inline u8 rd_get_status(struct ring_descr *rd) -{ - return rd->hw->rd_status; -} - -static inline dma_addr_t rd_get_addr(struct ring_descr *rd) -{ - dma_addr_t a; - - a = le32_to_cpu(rd->hw->rd_addr); - return (a & DMA_MASK_MSTRPAGE) | (MSTRPAGE_VALUE << 24); -} - -static inline u16 rd_get_count(struct ring_descr *rd) -{ - return le16_to_cpu(rd->hw->rd_count); -} - -/******************************************************************/ - -/* sw descriptor rings for rx, tx: - * - * operations follow producer-consumer paradigm, with the hw - * in the middle doing the processing. - * ring size must be power of two. - * - * producer advances r->tail after inserting for processing - * consumer advances r->head after removing processed rd - * ring is empty if head==tail / full if (tail+1)==head - */ - -struct vlsi_ring { - struct pci_dev *pdev; - int dir; - unsigned len; - unsigned size; - unsigned mask; - atomic_t head, tail; - struct ring_descr *rd; -}; - -/* ring processing helpers */ - -static inline struct ring_descr *ring_last(struct vlsi_ring *r) -{ - int t; - - t = atomic_read(&r->tail) & r->mask; - return (((t+1) & r->mask) == (atomic_read(&r->head) & r->mask)) ? NULL : &r->rd[t]; -} - -static inline struct ring_descr *ring_put(struct vlsi_ring *r) -{ - atomic_inc(&r->tail); - return ring_last(r); -} - -static inline struct ring_descr *ring_first(struct vlsi_ring *r) -{ - int h; - - h = atomic_read(&r->head) & r->mask; - return (h == (atomic_read(&r->tail) & r->mask)) ? NULL : &r->rd[h]; -} - -static inline struct ring_descr *ring_get(struct vlsi_ring *r) -{ - atomic_inc(&r->head); - return ring_first(r); -} - -/******************************************************************/ - -/* our private compound VLSI-PCI-IRDA device information */ - -typedef struct vlsi_irda_dev { - struct pci_dev *pdev; - struct net_device_stats stats; - - struct irlap_cb *irlap; - - struct qos_info qos; - - unsigned mode; - int baud, new_baud; - - dma_addr_t busaddr; - void *virtaddr; - struct vlsi_ring *tx_ring, *rx_ring; - - struct timeval last_rx; - - spinlock_t lock; - struct semaphore sem; - - u32 cfg_space[64/sizeof(u32)]; - u8 resume_ok; - struct proc_dir_entry *proc_entry; - -} vlsi_irda_dev_t; - -/********************************************************/ - -/* the remapped error flags we use for returning from frame - * post-processing in vlsi_process_tx/rx() after it was completed - * by the hardware. These functions either return the >=0 number - * of transfered bytes in case of success or the negative (-) - * of the or'ed error flags. - */ - -#define VLSI_TX_DROP 0x0001 -#define VLSI_TX_FIFO 0x0002 - -#define VLSI_RX_DROP 0x0100 -#define VLSI_RX_OVER 0x0200 -#define VLSI_RX_LENGTH 0x0400 -#define VLSI_RX_FRAME 0x0800 -#define VLSI_RX_CRC 0x1000 - -/********************************************************/ - -#endif /* IRDA_VLSI_FIR_H */ - diff -Nru a/include/net/irda/w83977af.h b/include/net/irda/w83977af.h --- a/include/net/irda/w83977af.h Sun Apr 18 13:42:41 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,53 +0,0 @@ -#ifndef W83977AF_H -#define W83977AF_H - -#define W977_EFIO_BASE 0x370 -#define W977_EFIO2_BASE 0x3f0 -#define W977_DEVICE_IR 0x06 - - -/* - * Enter extended function mode - */ -static inline void w977_efm_enter(unsigned int efio) -{ - outb(0x87, efio); - outb(0x87, efio); -} - -/* - * Select a device to configure - */ - -static inline void w977_select_device(__u8 devnum, unsigned int efio) -{ - outb(0x07, efio); - outb(devnum, efio+1); -} - -/* - * Write a byte to a register - */ -static inline void w977_write_reg(__u8 reg, __u8 value, unsigned int efio) -{ - outb(reg, efio); - outb(value, efio+1); -} - -/* - * read a byte from a register - */ -static inline __u8 w977_read_reg(__u8 reg, unsigned int efio) -{ - outb(reg, efio); - return inb(efio+1); -} - -/* - * Exit extended function mode - */ -static inline void w977_efm_exit(unsigned int efio) -{ - outb(0xAA, efio); -} -#endif diff -Nru a/include/net/irda/w83977af_ir.h b/include/net/irda/w83977af_ir.h --- a/include/net/irda/w83977af_ir.h Sun Apr 18 13:42:40 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,196 +0,0 @@ -/********************************************************************* - * - * Filename: w83977af_ir.h - * Version: - * Description: - * Status: Experimental. - * Author: Paul VanderSpek - * Created at: Thu Nov 19 13:55:34 1998 - * Modified at: Tue Jan 11 13:08:19 2000 - * Modified by: Dag Brattli - * - * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved. - * - * 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef W83977AF_IR_H -#define W83977AF_IR_H - -#include - -/* Flags for configuration register CRF0 */ -#define ENBNKSEL 0x01 -#define APEDCRC 0x02 -#define TXW4C 0x04 -#define RXW4C 0x08 - -/* Bank 0 */ -#define RBR 0x00 /* Receiver buffer register */ -#define TBR 0x00 /* Transmitter buffer register */ - -#define ICR 0x01 /* Interrupt configuration register */ -#define ICR_ERBRI 0x01 /* Receiver buffer register interrupt */ -#define ICR_ETBREI 0x02 /* Transeiver empty interrupt */ -#define ICR_EUSRI 0x04//* IR status interrupt */ -#define ICR_EHSRI 0x04 -#define ICR_ETXURI 0x04 /* Tx underrun */ -#define ICR_EDMAI 0x10 /* DMA interrupt */ -#define ICR_ETXTHI 0x20 /* Transmitter threshold interrupt */ -#define ICR_EFSFI 0x40 /* Frame status FIFO interrupt */ -#define ICR_ETMRI 0x80 /* Timer interrupt */ - -#define UFR 0x02 /* FIFO control register */ -#define UFR_EN_FIFO 0x01 /* Enable FIFO's */ -#define UFR_RXF_RST 0x02 /* Reset Rx FIFO */ -#define UFR_TXF_RST 0x04 /* Reset Tx FIFO */ -#define UFR_RXTL 0x80 /* Rx FIFO threshold (set to 16) */ -#define UFR_TXTL 0x20 /* Tx FIFO threshold (set to 17) */ - -#define ISR 0x02 /* Interrupt status register */ -#define ISR_RXTH_I 0x01 /* Receive threshold interrupt */ -#define ISR_TXEMP_I 0x02 /* Transmitter empty interrupt */ -#define ISR_FEND_I 0x04 -#define ISR_DMA_I 0x10 -#define ISR_TXTH_I 0x20 /* Transmitter threshold interrupt */ -#define ISR_FSF_I 0x40 -#define ISR_TMR_I 0x80 /* Timer interrupt */ - -#define UCR 0x03 /* Uart control register */ -#define UCR_DLS8 0x03 /* 8N1 */ - -#define SSR 0x03 /* Sets select register */ -#define SET0 UCR_DLS8 /* Make sure we keep 8N1 */ -#define SET1 (0x80|UCR_DLS8) /* Make sure we keep 8N1 */ -#define SET2 0xE0 -#define SET3 0xE4 -#define SET4 0xE8 -#define SET5 0xEC -#define SET6 0xF0 -#define SET7 0xF4 - -#define HCR 0x04 -#define HCR_MODE_MASK ~(0xD0) -#define HCR_SIR 0x60 -#define HCR_MIR_576 0x20 -#define HCR_MIR_1152 0x80 -#define HCR_FIR 0xA0 -#define HCR_EN_DMA 0x04 -#define HCR_EN_IRQ 0x08 -#define HCR_TX_WT 0x08 - -#define USR 0x05 /* IR status register */ -#define USR_RDR 0x01 /* Receive data ready */ -#define USR_TSRE 0x40 /* Transmitter empty? */ - -#define AUDR 0x07 -#define AUDR_SFEND 0x08 /* Set a frame end */ -#define AUDR_RXBSY 0x20 /* Rx busy */ -#define AUDR_UNDR 0x40 /* Transeiver underrun */ - -/* Set 2 */ -#define ABLL 0x00 /* Advanced baud rate divisor latch (low byte) */ -#define ABHL 0x01 /* Advanced baud rate divisor latch (high byte) */ - -#define ADCR1 0x02 -#define ADCR1_ADV_SL 0x01 -#define ADCR1_D_CHSW 0x08 /* the specs are wrong. its bit 3, not 4 */ -#define ADCR1_DMA_F 0x02 - -#define ADCR2 0x04 -#define ADCR2_TXFS32 0x01 -#define ADCR2_RXFS32 0x04 - -#define RXFDTH 0x07 - -/* Set 3 */ -#define AUID 0x00 - -/* Set 4 */ -#define TMRL 0x00 /* Timer value register (low byte) */ -#define TMRH 0x01 /* Timer value register (high byte) */ - -#define IR_MSL 0x02 /* Infrared mode select */ -#define IR_MSL_EN_TMR 0x01 /* Enable timer */ - -#define TFRLL 0x04 /* Transmitter frame length (low byte) */ -#define TFRLH 0x05 /* Transmitter frame length (high byte) */ -#define RFRLL 0x06 /* Receiver frame length (low byte) */ -#define RFRLH 0x07 /* Receiver frame length (high byte) */ - -/* Set 5 */ - -#define FS_FO 0x05 /* Frame status FIFO */ -#define FS_FO_FSFDR 0x80 /* Frame status FIFO data ready */ -#define FS_FO_LST_FR 0x40 /* Frame lost */ -#define FS_FO_MX_LEX 0x10 /* Max frame len exceeded */ -#define FS_FO_PHY_ERR 0x08 /* Physical layer error */ -#define FS_FO_CRC_ERR 0x04 -#define FS_FO_RX_OV 0x02 /* Receive overrun */ -#define FS_FO_FSF_OV 0x01 /* Frame status FIFO overrun */ -#define FS_FO_ERR_MSK 0x5f /* Error mask */ - -#define RFLFL 0x06 -#define RFLFH 0x07 - -/* Set 6 */ -#define IR_CFG2 0x00 -#define IR_CFG2_DIS_CRC 0x02 - -/* Set 7 */ -#define IRM_CR 0x07 /* Infrared module control register */ -#define IRM_CR_IRX_MSL 0x40 -#define IRM_CR_AF_MNT 0x80 /* Automatic format */ - -/* For storing entries in the status FIFO */ -struct st_fifo_entry { - int status; - int len; -}; - -struct st_fifo { - struct st_fifo_entry entries[10]; - int head; - int tail; - int len; -}; - -/* Private data for each instance */ -struct w83977af_ir { - struct st_fifo st_fifo; - - int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ - int tx_len; /* Number of frames in tx_buff */ - - struct net_device *netdev; /* Yes! we are some kind of netdevice */ - struct net_device_stats stats; - - struct irlap_cb *irlap; /* The link layer we are binded to */ - struct qos_info qos; /* QoS capabilities for this device */ - - chipio_t io; /* IrDA controller information */ - iobuff_t tx_buff; /* Transmit buffer */ - iobuff_t rx_buff; /* Receive buffer */ - - /* Note : currently locking is *very* incomplete, but this - * will get you started. Check in nsc-ircc.c for a proper - * locking strategy. - Jean II */ - spinlock_t lock; /* For serializing operations */ - - __u32 new_speed; -}; - -static inline void switch_bank( int iobase, int set) -{ - outb(set, iobase+SSR); -} - -#endif diff -Nru a/include/net/neighbour.h b/include/net/neighbour.h --- a/include/net/neighbour.h Sun Apr 18 13:42:41 2004 +++ b/include/net/neighbour.h Sun Apr 18 13:42:41 2004 @@ -281,6 +281,8 @@ return neigh_create(tbl, pkey, dev); } +#define LOCALLY_ENQUEUED -2 + #endif #endif diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h --- a/include/net/sctp/sctp.h Sun Apr 18 13:42:40 2004 +++ b/include/net/sctp/sctp.h Sun Apr 18 13:42:40 2004 @@ -1,5 +1,5 @@ /* SCTP kernel reference Implementation - * (C) Copyright IBM Corp. 2001, 2003 + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2003 Intel Corp. @@ -78,6 +78,7 @@ #include #include #include +#include #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include @@ -223,24 +224,6 @@ #define SCTP_INC_STATS_USER(field) SNMP_INC_STATS_USER(sctp_statistics, field) #define SCTP_DEC_STATS(field) SNMP_DEC_STATS(sctp_statistics, field) -/* Determine if this is a valid kernel address. */ -static inline int sctp_is_valid_kaddr(unsigned long addr) -{ - struct page *page; - - /* Make sure the address is not in the user address space. */ - if (addr < PAGE_OFFSET) - return 0; - - page = virt_to_page(addr); - - /* Is this page valid? */ - if (!virt_addr_valid(addr) || PageReserved(page)) - return 0; - - return 1; -} - #endif /* !TEST_FRAME */ @@ -357,7 +340,7 @@ /* Map an association to an assoc_id. */ static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) { - return (sctp_assoc_t) asoc; + return (asoc?asoc->assoc_id:NULL); } /* Look up the association by its id. */ @@ -518,6 +501,9 @@ extern struct proto sctp_prot; extern struct proc_dir_entry *proc_net_sctp; void sctp_put_port(struct sock *sk); + +extern struct idr sctp_assocs_id; +extern spinlock_t sctp_assocs_id_lock; /* Static inline functions. */ diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h --- a/include/net/sctp/structs.h Sun Apr 18 13:42:41 2004 +++ b/include/net/sctp/structs.h Sun Apr 18 13:42:41 2004 @@ -1,5 +1,5 @@ /* SCTP kernel reference Implementation - * (C) Copyright IBM Corp. 2001, 2003 + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001 Intel Corp. @@ -1282,11 +1282,8 @@ /* Associations on the same socket. */ struct list_head asocs; - /* This is a signature that lets us know that this is a - * struct sctp_association data structure. Used for mapping an - * association id to an association. - */ - __u32 eyecatcher; + /* association id. */ + sctp_assoc_t assoc_id; /* This is our parent endpoint. */ struct sctp_endpoint *ep; diff -Nru a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h --- a/include/net/sctp/ulpevent.h Sun Apr 18 13:42:40 2004 +++ b/include/net/sctp/ulpevent.h Sun Apr 18 13:42:40 2004 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -54,7 +54,13 @@ * growing this structure as it is at the maximum limit now. */ struct sctp_ulpevent { - struct sctp_sndrcvinfo sndrcvinfo; + struct sctp_association *asoc; + __u16 stream; + __u16 ssn; + __u16 flags; + __u32 ppid; + __u32 tsn; + __u32 cumtsn; int msg_flags; int iif; }; diff -Nru a/include/net/sock.h b/include/net/sock.h --- a/include/net/sock.h Sun Apr 18 13:42:41 2004 +++ b/include/net/sock.h Sun Apr 18 13:42:41 2004 @@ -382,6 +382,7 @@ SOCK_LINGER, SOCK_DESTROY, SOCK_BROADCAST, + SOCK_TIMESTAMP, }; static inline void sock_set_flag(struct sock *sk, enum sock_flags flag) @@ -561,8 +562,8 @@ extern void __release_sock(struct sock *sk); #define sock_owned_by_user(sk) ((sk)->sk_lock.owner) -extern void lock_sock(struct sock *sk); -extern void release_sock(struct sock *sk); +extern void FASTCALL(lock_sock(struct sock *sk)); +extern void FASTCALL(release_sock(struct sock *sk)); /* BH context may only use the following locking interface. */ #define bh_lock_sock(__sk) spin_lock(&((__sk)->sk_lock.slock)) @@ -623,9 +624,9 @@ extern int sock_no_listen(struct socket *, int); extern int sock_no_shutdown(struct socket *, int); extern int sock_no_getsockopt(struct socket *, int , int, - char *, int *); + char __user *, int __user *); extern int sock_no_setsockopt(struct socket *, int, int, - char *, int); + char __user *, int); extern int sock_no_sendmsg(struct kiocb *, struct socket *, struct msghdr *, size_t); extern int sock_no_recvmsg(struct kiocb *, struct socket *, @@ -1023,11 +1024,33 @@ static __inline__ void sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { - if (sk->sk_rcvtstamp) - put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(skb->stamp), &skb->stamp); - else - sk->sk_stamp = skb->stamp; -} + struct timeval *stamp = &skb->stamp; + if (sk->sk_rcvtstamp) { + /* Race occurred between timestamp enabling and packet + receiving. Fill in the current time for now. */ + if (stamp->tv_sec == 0) + do_gettimeofday(stamp); + put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval), + stamp); + } else + sk->sk_stamp = *stamp; +} + +extern atomic_t netstamp_needed; +extern void sock_enable_timestamp(struct sock *sk); +extern void sock_disable_timestamp(struct sock *sk); + +static inline void net_timestamp(struct timeval *stamp) +{ + if (atomic_read(&netstamp_needed)) + do_gettimeofday(stamp); + else { + stamp->tv_sec = 0; + stamp->tv_usec = 0; + } +} + +extern int sock_get_timestamp(struct sock *, struct timeval *); /* * Enable debug/info messages @@ -1035,8 +1058,10 @@ #if 0 #define NETDEBUG(x) do { } while (0) +#define LIMIT_NETDEBUG(x) do {} while(0) #else #define NETDEBUG(x) do { x; } while (0) +#define LIMIT_NETDEBUG(x) do { if (net_ratelimit()) { x; } } while(0) #endif /* diff -Nru a/include/sound/sndmagic.h b/include/sound/sndmagic.h --- a/include/sound/sndmagic.h Sun Apr 18 13:42:40 2004 +++ b/include/sound/sndmagic.h Sun Apr 18 13:42:40 2004 @@ -203,6 +203,7 @@ #define pdacf_t_magic 0xa15a4500 #define vortex_t_magic 0xa15a4601 #define atiixp_t_magic 0xa15a4701 +#define amd7930_t_magic 0xa15a4801 #else diff -Nru a/ipc/mqueue.c b/ipc/mqueue.c --- a/ipc/mqueue.c Sun Apr 18 13:42:41 2004 +++ b/ipc/mqueue.c Sun Apr 18 13:42:41 2004 @@ -65,8 +65,8 @@ struct msg_msg **messages; struct mq_attr attr; - struct sigevent notify; /* notify.sigev_notify == SIGEV_NONE means */ - pid_t notify_owner; /* no notification registered */ + struct sigevent notify; + pid_t notify_owner; struct sock *notify_sock; struct sk_buff *notify_cookie; @@ -122,7 +122,7 @@ init_waitqueue_head(&info->wait_q); INIT_LIST_HEAD(&info->e_wait_q[0].list); INIT_LIST_HEAD(&info->e_wait_q[1].list); - info->notify.sigev_notify = SIGEV_NONE; + info->notify_owner = 0; info->qsize = 0; memset(&info->attr, 0, sizeof(info->attr)); info->attr.mq_maxmsg = DFLT_MSGMAX; @@ -153,7 +153,7 @@ sb->s_magic = MQUEUE_MAGIC; sb->s_op = &mqueue_super_ops; - inode = mqueue_get_inode(sb, S_IFDIR | S_IRWXUGO); + inode = mqueue_get_inode(sb, S_IFDIR | S_ISVTX | S_IRWXUGO); if (!inode) return -ENOMEM; @@ -286,11 +286,11 @@ snprintf(buffer, sizeof(buffer), "QSIZE:%-10lu NOTIFY:%-5d SIGNO:%-5d NOTIFY_PID:%-6d\n", info->qsize, - info->notify.sigev_notify, - (info->notify.sigev_notify == SIGEV_SIGNAL ) ? + info->notify_owner ? info->notify.sigev_notify : 0, + (info->notify_owner && + info->notify.sigev_notify == SIGEV_SIGNAL) ? info->notify.sigev_signo : 0, - (info->notify.sigev_notify != SIGEV_NONE) ? - info->notify_owner : 0); + info->notify_owner); spin_unlock(&info->lock); buffer[sizeof(buffer)-1] = '\0'; slen = strlen(buffer)+1; @@ -315,8 +315,7 @@ struct mqueue_inode_info *info = MQUEUE_I(filp->f_dentry->d_inode); spin_lock(&info->lock); - if (info->notify.sigev_notify != SIGEV_NONE && - current->tgid == info->notify_owner) + if (current->tgid == info->notify_owner) remove_notification(info); spin_unlock(&info->lock); @@ -455,11 +454,14 @@ * waiting synchronously for message AND state of queue changed from * empty to not empty. Here we are sure that no one is waiting * synchronously. */ - if (info->notify.sigev_notify != SIGEV_NONE && - info->attr.mq_curmsgs == 1) { - /* sends signal */ - if (info->notify.sigev_notify == SIGEV_SIGNAL) { - struct siginfo sig_i; + if (info->notify_owner && + info->attr.mq_curmsgs == 1) { + struct siginfo sig_i; + switch (info->notify.sigev_notify) { + case SIGEV_NONE: + break; + case SIGEV_SIGNAL: + /* sends signal */ sig_i.si_signo = info->notify.sigev_signo; sig_i.si_errno = 0; @@ -470,13 +472,15 @@ kill_proc_info(info->notify.sigev_signo, &sig_i, info->notify_owner); - } else if (info->notify.sigev_notify == SIGEV_THREAD) { + break; + case SIGEV_THREAD: set_cookie(info->notify_cookie, NOTIFY_WOKENUP); netlink_sendskb(info->notify_sock, info->notify_cookie, 0); + break; } /* after notification unregisters process */ - info->notify.sigev_notify = SIGEV_NONE; + info->notify_owner = 0; } wake_up(&info->wait_q); } @@ -514,11 +518,12 @@ static void remove_notification(struct mqueue_inode_info *info) { - if (info->notify.sigev_notify == SIGEV_THREAD) { + if (info->notify_owner != 0 && + info->notify.sigev_notify == SIGEV_THREAD) { set_cookie(info->notify_cookie, NOTIFY_REMOVED); netlink_sendskb(info->notify_sock, info->notify_cookie, 0); } - info->notify.sigev_notify = SIGEV_NONE; + info->notify_owner = 0; } /* @@ -641,6 +646,7 @@ goto out_putfd; } + set_close_on_exec(fd, 1); fd_install(fd, filp); goto out_upsem; @@ -679,10 +685,6 @@ goto out_err; } - if (permission(dentry->d_inode, MAY_WRITE, NULL)) { - err = -EACCES; - goto out_err; - } inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); @@ -908,9 +910,9 @@ } /* - * Notes: the case when user wants us to deregister (with NULL as pointer - * or SIGEV_NONE) and he isn't currently owner of notification will be - * silently discarded. It isn't explicitly defined in the POSIX. + * Notes: the case when user wants us to deregister (with NULL as pointer) + * and he isn't currently owner of notification, will be silently discarded. + * It isn't explicitly defined in the POSIX. */ asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification) @@ -925,9 +927,7 @@ nc = NULL; sock = NULL; - if (u_notification == NULL) { - notification.sigev_notify = SIGEV_NONE; - } else { + if (u_notification != NULL) { if (copy_from_user(¬ification, u_notification, sizeof(struct sigevent))) return -EFAULT; @@ -993,35 +993,31 @@ ret = 0; spin_lock(&info->lock); - switch (notification.sigev_notify) { - case SIGEV_NONE: - if (info->notify.sigev_notify != SIGEV_NONE && - info->notify_owner == current->tgid) { + if (u_notification == NULL) { + if (info->notify_owner == current->tgid) { remove_notification(info); inode->i_atime = inode->i_ctime = CURRENT_TIME; } - break; - case SIGEV_THREAD: - if (info->notify.sigev_notify != SIGEV_NONE) { - ret = -EBUSY; + } else if (info->notify_owner != 0) { + ret = -EBUSY; + } else { + switch (notification.sigev_notify) { + case SIGEV_NONE: + info->notify.sigev_notify = SIGEV_NONE; break; - } - info->notify_sock = sock; - info->notify_cookie = nc; - sock = NULL; - nc = NULL; - info->notify.sigev_notify = SIGEV_THREAD; - info->notify_owner = current->tgid; - inode->i_atime = inode->i_ctime = CURRENT_TIME; - break; - case SIGEV_SIGNAL: - if (info->notify.sigev_notify != SIGEV_NONE) { - ret = -EBUSY; + case SIGEV_THREAD: + info->notify_sock = sock; + info->notify_cookie = nc; + sock = NULL; + nc = NULL; + info->notify.sigev_notify = SIGEV_THREAD; + break; + case SIGEV_SIGNAL: + info->notify.sigev_signo = notification.sigev_signo; + info->notify.sigev_value = notification.sigev_value; + info->notify.sigev_notify = SIGEV_SIGNAL; break; } - info->notify.sigev_signo = notification.sigev_signo; - info->notify.sigev_value = notification.sigev_value; - info->notify.sigev_notify = SIGEV_SIGNAL; info->notify_owner = current->tgid; inode->i_atime = inode->i_ctime = CURRENT_TIME; } diff -Nru a/kernel/module.c b/kernel/module.c --- a/kernel/module.c Sun Apr 18 13:42:41 2004 +++ b/kernel/module.c Sun Apr 18 13:42:41 2004 @@ -1003,6 +1003,8 @@ /* We compiled with -fno-common. These are not supposed to happen. */ DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name); + printk("%s: please compile with -fno-common\n", + mod->name); ret = -ENOEXEC; break; diff -Nru a/kernel/signal.c b/kernel/signal.c --- a/kernel/signal.c Sun Apr 18 13:42:40 2004 +++ b/kernel/signal.c Sun Apr 18 13:42:40 2004 @@ -2052,7 +2052,6 @@ case __SI_MESGQ: /* But this is */ err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); - err |= __put_user(from->si_int, &to->si_int); err |= __put_user(from->si_ptr, &to->si_ptr); break; default: /* this is just in case for now ... */ diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c --- a/kernel/sysctl.c Sun Apr 18 13:42:40 2004 +++ b/kernel/sysctl.c Sun Apr 18 13:42:40 2004 @@ -93,6 +93,7 @@ #ifdef __sparc__ extern char reboot_command []; extern int stop_a_enabled; +extern int scons_pwroff; #endif #ifdef __hppa__ @@ -321,6 +322,14 @@ .ctl_name = KERN_SPARC_STOP_A, .procname = "stop-a", .data = &stop_a_enabled, + .maxlen = sizeof (int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = KERN_SPARC_SCONS_PWROFF, + .procname = "scons-poweroff", + .data = &scons_pwroff, .maxlen = sizeof (int), .mode = 0644, .proc_handler = &proc_dointvec, diff -Nru a/lib/kobject.c b/lib/kobject.c --- a/lib/kobject.c Sun Apr 18 13:42:41 2004 +++ b/lib/kobject.c Sun Apr 18 13:42:41 2004 @@ -349,16 +349,16 @@ /* * Need more space? Allocate it and try again */ - name = kmalloc(need,GFP_KERNEL); + limit = need + 1; + name = kmalloc(limit,GFP_KERNEL); if (!name) { error = -ENOMEM; goto Done; } - limit = need; need = vsnprintf(name,limit,fmt,args); /* Still? Give up. */ - if (need > limit) { + if (need >= limit) { kfree(name); error = -EFAULT; goto Done; diff -Nru a/lib/radix-tree.c b/lib/radix-tree.c --- a/lib/radix-tree.c Sun Apr 18 13:42:40 2004 +++ b/lib/radix-tree.c Sun Apr 18 13:42:40 2004 @@ -30,12 +30,7 @@ #include #include -/* - * Radix tree node definition. - * - * RADIX_TREE_MAP_SHIFT must be >= log2(BITS_PER_LONG). Otherwise the tags - * array will have zero size and the set_tag() arithmetic will go wrong. - */ + #ifdef __KERNEL__ #define RADIX_TREE_MAP_SHIFT 6 #else diff -Nru a/mm/filemap.c b/mm/filemap.c --- a/mm/filemap.c Sun Apr 18 13:42:40 2004 +++ b/mm/filemap.c Sun Apr 18 13:42:40 2004 @@ -62,7 +62,7 @@ * ->mapping->tree_lock * * ->i_sem - * ->i_shared_sem (truncate->invalidate_mmap_range) + * ->i_shared_sem (truncate->unmap_mapping_range) * * ->mmap_sem * ->i_shared_sem (various places) @@ -127,7 +127,7 @@ if (mapping->a_ops && mapping->a_ops->sync_page) return mapping->a_ops->sync_page(page); } else if (PageSwapCache(page)) { - swap_unplug_io_fn(NULL); + swap_unplug_io_fn(page); } return 0; } @@ -551,7 +551,7 @@ /* * Like find_get_pages, except we only return pages which are tagged with - * `tag'. We update *start to index the next page for the traversal. + * `tag'. We update *index to index the next page for the traversal. */ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, int tag, unsigned int nr_pages, struct page **pages) @@ -1363,11 +1363,7 @@ * If a nonlinear mapping then store the file page offset * in the pte. */ - unsigned long pgidx; - pgidx = (addr - vma->vm_start) >> PAGE_SHIFT; - pgidx += vma->vm_pgoff; - pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT; - if (pgoff != pgidx) { + if (pgoff != linear_page_index(vma, addr)) { err = install_file_pte(mm, vma, addr, pgoff, prot); if (err) return err; diff -Nru a/mm/madvise.c b/mm/madvise.c --- a/mm/madvise.c Sun Apr 18 13:42:40 2004 +++ b/mm/madvise.c Sun Apr 18 13:42:40 2004 @@ -95,7 +95,7 @@ if (vma->vm_flags & VM_LOCKED) return -EINVAL; - zap_page_range(vma, start, end - start); + zap_page_range(vma, start, end - start, NULL); return 0; } diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Sun Apr 18 13:42:41 2004 +++ b/mm/memory.c Sun Apr 18 13:42:41 2004 @@ -384,9 +384,19 @@ return -ENOMEM; } -static void -zap_pte_range(struct mmu_gather *tlb, pmd_t * pmd, - unsigned long address, unsigned long size) +/* + * Parameter block passed down to zap_pte_range in exceptional cases. + */ +struct zap_details { + struct vm_area_struct *nonlinear_vma; /* Check page->index if set */ + struct address_space *check_mapping; /* Check page->mapping if set */ + pgoff_t first_index; /* Lowest page->index to unmap */ + pgoff_t last_index; /* Highest page->index to unmap */ +}; + +static void zap_pte_range(struct mmu_gather *tlb, + pmd_t *pmd, unsigned long address, + unsigned long size, struct zap_details *details) { unsigned long offset; pte_t *ptep; @@ -408,35 +418,64 @@ if (pte_none(pte)) continue; if (pte_present(pte)) { + struct page *page = NULL; unsigned long pfn = pte_pfn(pte); - - pte = ptep_get_and_clear(ptep); - tlb_remove_tlb_entry(tlb, ptep, address+offset); if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - if (!PageReserved(page)) { - if (pte_dirty(pte)) - set_page_dirty(page); - if (pte_young(pte) && - page_mapping(page)) - mark_page_accessed(page); - tlb->freed++; - page_remove_rmap(page, ptep); - tlb_remove_page(tlb, page); - } + page = pfn_to_page(pfn); + if (PageReserved(page)) + page = NULL; + } + if (unlikely(details) && page) { + /* + * unmap_shared_mapping_pages() wants to + * invalidate cache without truncating: + * unmap shared but keep private pages. + */ + if (details->check_mapping && + details->check_mapping != page->mapping) + continue; + /* + * Each page->index must be checked when + * invalidating or truncating nonlinear. + */ + if (details->nonlinear_vma && + (page->index < details->first_index || + page->index > details->last_index)) + continue; } - } else { - if (!pte_file(pte)) - free_swap_and_cache(pte_to_swp_entry(pte)); - pte_clear(ptep); + pte = ptep_get_and_clear(ptep); + tlb_remove_tlb_entry(tlb, ptep, address+offset); + if (unlikely(!page)) + continue; + if (unlikely(details) && details->nonlinear_vma + && linear_page_index(details->nonlinear_vma, + address+offset) != page->index) + set_pte(ptep, pgoff_to_pte(page->index)); + if (pte_dirty(pte)) + set_page_dirty(page); + if (pte_young(pte) && page_mapping(page)) + mark_page_accessed(page); + tlb->freed++; + page_remove_rmap(page, ptep); + tlb_remove_page(tlb, page); + continue; } + /* + * If details->check_mapping, we leave swap entries; + * if details->nonlinear_vma, we leave file entries. + */ + if (unlikely(details)) + continue; + if (!pte_file(pte)) + free_swap_and_cache(pte_to_swp_entry(pte)); + pte_clear(ptep); } pte_unmap(ptep-1); } -static void -zap_pmd_range(struct mmu_gather *tlb, pgd_t * dir, - unsigned long address, unsigned long size) +static void zap_pmd_range(struct mmu_gather *tlb, + pgd_t * dir, unsigned long address, + unsigned long size, struct zap_details *details) { pmd_t * pmd; unsigned long end; @@ -453,28 +492,23 @@ if (end > ((address + PGDIR_SIZE) & PGDIR_MASK)) end = ((address + PGDIR_SIZE) & PGDIR_MASK); do { - zap_pte_range(tlb, pmd, address, end - address); + zap_pte_range(tlb, pmd, address, end - address, details); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); } -void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma, - unsigned long address, unsigned long end) +static void unmap_page_range(struct mmu_gather *tlb, + struct vm_area_struct *vma, unsigned long address, + unsigned long end, struct zap_details *details) { pgd_t * dir; - if (is_vm_hugetlb_page(vma)) { - unmap_hugepage_range(vma, address, end); - return; - } - BUG_ON(address >= end); - dir = pgd_offset(vma->vm_mm, address); tlb_start_vma(tlb, vma); do { - zap_pmd_range(tlb, dir, address, end - address); + zap_pmd_range(tlb, dir, address, end - address, details); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); @@ -504,6 +538,7 @@ * @start_addr: virtual address at which to start unmapping * @end_addr: virtual address at which to end unmapping * @nr_accounted: Place number of unmapped pages in vm-accountable vma's here + * @details: details of nonlinear truncation or shared cache invalidation * * Returns the number of vma's which were covered by the unmapping. * @@ -524,22 +559,14 @@ */ int unmap_vmas(struct mmu_gather **tlbp, struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, unsigned long *nr_accounted) + unsigned long end_addr, unsigned long *nr_accounted, + struct zap_details *details) { unsigned long zap_bytes = ZAP_BLOCK_SIZE; unsigned long tlb_start = 0; /* For tlb_finish_mmu */ int tlb_start_valid = 0; int ret = 0; - if (vma) { /* debug. killme. */ - if (end_addr <= vma->vm_start) - printk("%s: end_addr(0x%08lx) <= vm_start(0x%08lx)\n", - __FUNCTION__, end_addr, vma->vm_start); - if (start_addr >= vma->vm_end) - printk("%s: start_addr(0x%08lx) <= vm_end(0x%08lx)\n", - __FUNCTION__, start_addr, vma->vm_end); - } - for ( ; vma && vma->vm_start < end_addr; vma = vma->vm_next) { unsigned long start; unsigned long end; @@ -558,17 +585,20 @@ while (start != end) { unsigned long block; - if (is_vm_hugetlb_page(vma)) - block = end - start; - else - block = min(zap_bytes, end - start); - if (!tlb_start_valid) { tlb_start = start; tlb_start_valid = 1; } - unmap_page_range(*tlbp, vma, start, start + block); + if (is_vm_hugetlb_page(vma)) { + block = end - start; + unmap_hugepage_range(vma, start, end); + } else { + block = min(zap_bytes, end - start); + unmap_page_range(*tlbp, vma, start, + start + block, details); + } + start += block; zap_bytes -= block; if ((long)zap_bytes > 0) @@ -582,9 +612,6 @@ } zap_bytes = ZAP_BLOCK_SIZE; } - if (vma->vm_next && vma->vm_next->vm_start < vma->vm_end) - printk("%s: VMA list is not sorted correctly!\n", - __FUNCTION__); } return ret; } @@ -594,9 +621,10 @@ * @vma: vm_area_struct holding the applicable pages * @address: starting address of pages to zap * @size: number of bytes to zap + * @details: details of nonlinear truncation or shared cache invalidation */ -void zap_page_range(struct vm_area_struct *vma, - unsigned long address, unsigned long size) +void zap_page_range(struct vm_area_struct *vma, unsigned long address, + unsigned long size, struct zap_details *details) { struct mm_struct *mm = vma->vm_mm; struct mmu_gather *tlb; @@ -613,7 +641,7 @@ lru_add_drain(); spin_lock(&mm->page_table_lock); tlb = tlb_gather_mmu(mm, 0); - unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted); + unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details); tlb_finish_mmu(tlb, address, end); spin_unlock(&mm->page_table_lock); } @@ -1130,46 +1158,46 @@ } /* - * Helper function for invalidate_mmap_range(). - * Both hba and hlen are page numbers in PAGE_SIZE units. - * An hlen of zero blows away the entire portion file after hba. + * Helper function for unmap_mapping_range(). */ -static void -invalidate_mmap_range_list(struct list_head *head, - unsigned long const hba, - unsigned long const hlen) -{ - struct list_head *curr; - unsigned long hea; /* last page of hole. */ - unsigned long vba; - unsigned long vea; /* last page of corresponding uva hole. */ - struct vm_area_struct *vp; - unsigned long zba; - unsigned long zea; - - hea = hba + hlen - 1; /* avoid overflow. */ - if (hea < hba) - hea = ULONG_MAX; - list_for_each(curr, head) { - vp = list_entry(curr, struct vm_area_struct, shared); - vba = vp->vm_pgoff; - vea = vba + ((vp->vm_end - vp->vm_start) >> PAGE_SHIFT) - 1; - if (hea < vba || vea < hba) - continue; /* Mapping disjoint from hole. */ - zba = (hba <= vba) ? vba : hba; - zea = (vea <= hea) ? vea : hea; - zap_page_range(vp, - ((zba - vba) << PAGE_SHIFT) + vp->vm_start, - (zea - zba + 1) << PAGE_SHIFT); +static void unmap_mapping_range_list(struct list_head *head, + struct zap_details *details) +{ + struct vm_area_struct *vma; + pgoff_t vba, vea, zba, zea; + + list_for_each_entry(vma, head, shared) { + if (unlikely(vma->vm_flags & VM_NONLINEAR)) { + details->nonlinear_vma = vma; + zap_page_range(vma, vma->vm_start, + vma->vm_end - vma->vm_start, details); + details->nonlinear_vma = NULL; + continue; + } + vba = vma->vm_pgoff; + vea = vba + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) - 1; + /* Assume for now that PAGE_CACHE_SHIFT == PAGE_SHIFT */ + if (vba > details->last_index || vea < details->first_index) + continue; /* Mapping disjoint from hole. */ + zba = details->first_index; + if (zba < vba) + zba = vba; + zea = details->last_index; + if (zea > vea) + zea = vea; + zap_page_range(vma, + ((zba - vba) << PAGE_SHIFT) + vma->vm_start, + (zea - zba + 1) << PAGE_SHIFT, + details->check_mapping? details: NULL); } } /** - * invalidate_mmap_range - invalidate the portion of all mmaps + * unmap_mapping_range - unmap the portion of all mmaps * in the specified address_space corresponding to the specified * page range in the underlying file. - * @address_space: the address space containing mmaps to be invalidated. - * @holebegin: byte in first page to invalidate, relative to the start of + * @address_space: the address space containing mmaps to be unmapped. + * @holebegin: byte in first page to unmap, relative to the start of * the underlying file. This will be rounded down to a PAGE_SIZE * boundary. Note that this is different from vmtruncate(), which * must keep the partial page. In contrast, we must get rid of @@ -1177,31 +1205,45 @@ * @holelen: size of prospective hole in bytes. This will be rounded * up to a PAGE_SIZE boundary. A holelen of zero truncates to the * end of the file. + * @even_cows: 1 when truncating a file, unmap even private COWed pages; + * but 0 when invalidating pagecache, don't throw away private data. */ -void invalidate_mmap_range(struct address_space *mapping, - loff_t const holebegin, loff_t const holelen) +void unmap_mapping_range(struct address_space *mapping, + loff_t const holebegin, loff_t const holelen, int even_cows) { - unsigned long hba = holebegin >> PAGE_SHIFT; - unsigned long hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; + struct zap_details details; + pgoff_t hba = holebegin >> PAGE_SHIFT; + pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; /* Check for overflow. */ if (sizeof(holelen) > sizeof(hlen)) { long long holeend = (holebegin + holelen + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (holeend & ~(long long)ULONG_MAX) hlen = ULONG_MAX - hba + 1; } + + details.check_mapping = even_cows? NULL: mapping; + details.nonlinear_vma = NULL; + details.first_index = hba; + details.last_index = hba + hlen - 1; + if (details.last_index < details.first_index) + details.last_index = ULONG_MAX; + down(&mapping->i_shared_sem); /* Protect against page fault */ atomic_inc(&mapping->truncate_count); if (unlikely(!list_empty(&mapping->i_mmap))) - invalidate_mmap_range_list(&mapping->i_mmap, hba, hlen); + unmap_mapping_range_list(&mapping->i_mmap, &details); + + /* Don't waste time to check mapping on fully shared vmas */ + details.check_mapping = NULL; + if (unlikely(!list_empty(&mapping->i_mmap_shared))) - invalidate_mmap_range_list(&mapping->i_mmap_shared, hba, hlen); + unmap_mapping_range_list(&mapping->i_mmap_shared, &details); up(&mapping->i_shared_sem); } -EXPORT_SYMBOL_GPL(invalidate_mmap_range); +EXPORT_SYMBOL(unmap_mapping_range); /* * Handle all mappings that got truncated by a "truncate()" @@ -1219,7 +1261,7 @@ if (inode->i_size < offset) goto do_expand; i_size_write(inode, offset); - invalidate_mmap_range(mapping, offset + PAGE_SIZE - 1, 0); + unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); truncate_inode_pages(mapping, offset); goto out_truncate; @@ -1498,7 +1540,7 @@ spin_lock(&mm->page_table_lock); /* * For a file-backed vma, someone could have truncated or otherwise - * invalidated this page. If invalidate_mmap_range got called, + * invalidated this page. If unmap_mapping_range got called, * retry getting the page. */ if (mapping && diff -Nru a/mm/mmap.c b/mm/mmap.c --- a/mm/mmap.c Sun Apr 18 13:42:41 2004 +++ b/mm/mmap.c Sun Apr 18 13:42:41 2004 @@ -728,7 +728,7 @@ fput(file); /* Undo any partial mapping done by a device driver. */ - zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start); + zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, NULL); free_vma: kmem_cache_free(vm_area_cachep, vma); unacct_error: @@ -1160,7 +1160,7 @@ lru_add_drain(); tlb = tlb_gather_mmu(mm, 0); - unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted); + unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL); vm_unacct_memory(nr_accounted); if (is_hugepage_only_range(start, end - start)) @@ -1446,7 +1446,7 @@ flush_cache_mm(mm); /* Use ~0UL here to ensure all VMAs in the mm are unmapped */ mm->map_count -= unmap_vmas(&tlb, mm, mm->mmap, 0, - ~0UL, &nr_accounted); + ~0UL, &nr_accounted, NULL); vm_unacct_memory(nr_accounted); BUG_ON(mm->map_count); /* This is just debugging */ clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); @@ -1498,9 +1498,11 @@ * Copy the vma structure to a new location in the same mm, * prior to moving page table entries, to effect an mremap move. */ -struct vm_area_struct *copy_vma(struct vm_area_struct *vma, +struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, unsigned long addr, unsigned long len, unsigned long pgoff) { + struct vm_area_struct *vma = *vmap; + unsigned long vma_start = vma->vm_start; struct mm_struct *mm = vma->vm_mm; struct vm_area_struct *new_vma, *prev; struct rb_node **rb_link, *rb_parent; @@ -1508,7 +1510,14 @@ find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); new_vma = vma_merge(mm, prev, rb_parent, addr, addr + len, vma->vm_flags, vma->vm_file, pgoff); - if (!new_vma) { + if (new_vma) { + /* + * Source vma may have been merged into new_vma + */ + if (vma_start >= new_vma->vm_start && + vma_start < new_vma->vm_end) + *vmap = new_vma; + } else { new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (new_vma) { *new_vma = *vma; @@ -1524,25 +1533,4 @@ } } return new_vma; -} - -/* - * Position vma after prev in shared file list: - * for mremap move error recovery racing against vmtruncate. - */ -void vma_relink_file(struct vm_area_struct *vma, struct vm_area_struct *prev) -{ - struct mm_struct *mm = vma->vm_mm; - struct address_space *mapping; - - if (vma->vm_file) { - mapping = vma->vm_file->f_mapping; - if (mapping) { - down(&mapping->i_shared_sem); - spin_lock(&mm->page_table_lock); - list_move(&vma->shared, &prev->shared); - spin_unlock(&mm->page_table_lock); - up(&mapping->i_shared_sem); - } - } } diff -Nru a/mm/mprotect.c b/mm/mprotect.c --- a/mm/mprotect.c Sun Apr 18 13:42:41 2004 +++ b/mm/mprotect.c Sun Apr 18 13:42:41 2004 @@ -114,10 +114,11 @@ mprotect_attempt_merge(struct vm_area_struct *vma, struct vm_area_struct *prev, unsigned long end, int newflags) { - struct mm_struct * mm = vma->vm_mm; + struct mm_struct * mm; if (!prev || !vma) return 0; + mm = vma->vm_mm; if (prev->vm_end != vma->vm_start) return 0; if (!can_vma_merge(prev, newflags)) diff -Nru a/mm/mremap.c b/mm/mremap.c --- a/mm/mremap.c Sun Apr 18 13:42:41 2004 +++ b/mm/mremap.c Sun Apr 18 13:42:41 2004 @@ -169,6 +169,7 @@ unsigned long new_len, unsigned long new_addr) { struct mm_struct *mm = vma->vm_mm; + struct address_space *mapping = NULL; struct vm_area_struct *new_vma; unsigned long vm_flags = vma->vm_flags; unsigned long new_pgoff; @@ -184,30 +185,35 @@ return -ENOMEM; new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT); - new_vma = copy_vma(vma, new_addr, new_len, new_pgoff); + new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff); if (!new_vma) return -ENOMEM; + if (vma->vm_file) { + /* + * Subtle point from Rajesh Venkatasubramanian: before + * moving file-based ptes, we must lock vmtruncate out, + * since it might clean the dst vma before the src vma, + * and we propagate stale pages into the dst afterward. + */ + mapping = vma->vm_file->f_mapping; + down(&mapping->i_shared_sem); + } moved_len = move_page_tables(vma, new_addr, old_addr, old_len); if (moved_len < old_len) { /* * On error, move entries back from new area to old, * which will succeed since page tables still there, * and then proceed to unmap new area instead of old. - * - * Subtle point from Rajesh Venkatasubramanian: before - * moving file-based ptes, move new_vma before old vma - * in the i_mmap or i_mmap_shared list, so when racing - * against vmtruncate we cannot propagate pages to be - * truncated back from new_vma into just cleaned old. */ - vma_relink_file(vma, new_vma); move_page_tables(new_vma, old_addr, new_addr, moved_len); vma = new_vma; old_len = new_len; old_addr = new_addr; new_addr = -ENOMEM; } + if (mapping) + up(&mapping->i_shared_sem); /* Conceal VM_ACCOUNT so old reservation is not undone */ if (vm_flags & VM_ACCOUNT) { diff -Nru a/mm/nommu.c b/mm/nommu.c --- a/mm/nommu.c Sun Apr 18 13:42:41 2004 +++ b/mm/nommu.c Sun Apr 18 13:42:41 2004 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -570,9 +569,5 @@ } void pte_chain_init(void) -{ -} - -void swap_unplug_io_fn(struct backing_dev_info *) { } diff -Nru a/mm/rmap.c b/mm/rmap.c --- a/mm/rmap.c Sun Apr 18 13:42:41 2004 +++ b/mm/rmap.c Sun Apr 18 13:42:41 2004 @@ -359,16 +359,12 @@ set_pte(ptep, swp_entry_to_pte(entry)); BUG_ON(pte_file(*ptep)); } else { - unsigned long pgidx; /* * If a nonlinear mapping then store the file page offset * in the pte. */ BUG_ON(!page->mapping); - pgidx = (address - vma->vm_start) >> PAGE_SHIFT; - pgidx += vma->vm_pgoff; - pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT; - if (page->index != pgidx) { + if (page->index != linear_page_index(vma, address)) { set_pte(ptep, pgoff_to_pte(page->index)); BUG_ON(!pte_file(*ptep)); } diff -Nru a/mm/shmem.c b/mm/shmem.c --- a/mm/shmem.c Sun Apr 18 13:42:41 2004 +++ b/mm/shmem.c Sun Apr 18 13:42:41 2004 @@ -1055,11 +1055,7 @@ * If a nonlinear mapping then store the file page * offset in the pte. */ - unsigned long pgidx; - pgidx = (addr - vma->vm_start) >> PAGE_SHIFT; - pgidx += vma->vm_pgoff; - pgidx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT; - if (pgoff != pgidx) { + if (pgoff != linear_page_index(vma, addr)) { err = install_file_pte(mm, vma, addr, pgoff, prot); if (err) return err; diff -Nru a/mm/swap_state.c b/mm/swap_state.c --- a/mm/swap_state.c Sun Apr 18 13:42:41 2004 +++ b/mm/swap_state.c Sun Apr 18 13:42:41 2004 @@ -25,13 +25,13 @@ }; static struct backing_dev_info swap_backing_dev_info = { - .memory_backed = 1, /* Does not contribute to dirty memory */ - .unplug_io_fn = swap_unplug_io_fn, + .state = 0, /* uncongested */ }; struct address_space swapper_space = { .page_tree = RADIX_TREE_INIT(GFP_ATOMIC), .tree_lock = SPIN_LOCK_UNLOCKED, + .nrpages = 0, /* total_swapcache_pages */ .a_ops = &swap_aops, .backing_dev_info = &swap_backing_dev_info, }; diff -Nru a/mm/swapfile.c b/mm/swapfile.c --- a/mm/swapfile.c Sun Apr 18 13:42:40 2004 +++ b/mm/swapfile.c Sun Apr 18 13:42:40 2004 @@ -86,19 +86,26 @@ BUG(); } -void swap_unplug_io_fn(struct backing_dev_info *unused_bdi) +/* + * Unlike a standard unplug_io_fn, swap_unplug_io_fn is never called + * through swap's backing_dev_info (which is only used by shrink_list), + * but directly from sync_page when PageSwapCache: and takes the page + * as argument, so that it can find the right device from swp_entry_t. + */ +void swap_unplug_io_fn(struct page *page) { - int i; + swp_entry_t entry; down(&swap_bdevs_sem); - for (i = 0; i < MAX_SWAPFILES; i++) { - struct block_device *bdev = swap_bdevs[i]; + entry.val = page->private; + if (PageSwapCache(page)) { + struct block_device *bdev = swap_bdevs[swp_type(entry)]; struct backing_dev_info *bdi; - if (bdev == NULL) - break; - bdi = bdev->bd_inode->i_mapping->backing_dev_info; - (*bdi->unplug_io_fn)(bdi); + if (bdev) { + bdi = bdev->bd_inode->i_mapping->backing_dev_info; + (*bdi->unplug_io_fn)(bdi); + } } up(&swap_bdevs_sem); } diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h --- a/net/8021q/vlan.h Sun Apr 18 13:42:41 2004 +++ b/net/8021q/vlan.h Sun Apr 18 13:42:41 2004 @@ -19,8 +19,8 @@ I'll bet they might prove useful again... --Ben -#define VLAN_MEM_DBG(x, y, z) printk(VLAN_DBG __FUNCTION__ ": " x, y, z); -#define VLAN_FMEM_DBG(x, y) printk(VLAN_DBG __FUNCTION__ ": " x, y); +#define VLAN_MEM_DBG(x, y, z) printk(VLAN_DBG "%s: " x, __FUNCTION__, y, z); +#define VLAN_FMEM_DBG(x, y) printk(VLAN_DBG "%s: " x, __FUNCTION__, y); */ /* This way they don't do anything! */ diff -Nru a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c --- a/net/8021q/vlanproc.c Sun Apr 18 13:42:40 2004 +++ b/net/8021q/vlanproc.c Sun Apr 18 13:42:40 2004 @@ -220,7 +220,7 @@ } #ifdef VLAN_DEBUG - printk(VLAN_DBG __FUNCTION__ ": dev: %p\n", vlandev); + printk(VLAN_DBG "%s: dev: %p\n", __FUNCTION__, vlandev); #endif /** NOTE: This will consume the memory pointed to by dent, it seems. */ diff -Nru a/net/Kconfig b/net/Kconfig --- a/net/Kconfig Sun Apr 18 13:42:40 2004 +++ b/net/Kconfig Sun Apr 18 13:42:40 2004 @@ -129,59 +129,6 @@ source "net/ipv6/Kconfig" -config DECNET - tristate "DECnet Support" - ---help--- - The DECnet networking protocol was used in many products made by - Digital (now Compaq). It provides reliable stream and sequenced - packet communications over which run a variety of services similar - to those which run over TCP/IP. - - To find some tools to use with the kernel layer support, please - look at Patrick Caulfield's web site: - . - - More detailed documentation is available in - . - - Be sure to say Y to "/proc file system support" and "Sysctl support" - below when using DECnet, since you will need sysctl support to aid - in configuration at run time. - - The DECnet code is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module is called decnet. - -source "net/decnet/Kconfig" - -config BRIDGE - tristate "802.1d Ethernet Bridging" - ---help--- - If you say Y here, then your Linux box will be able to act as an - Ethernet bridge, which means that the different Ethernet segments it - is connected to will appear as one Ethernet to the participants. - Several such bridges can work together to create even larger - networks of Ethernets using the IEEE 802.1 spanning tree algorithm. - As this is a standard, Linux bridges will cooperate properly with - other third party bridge products. - - In order to use the Ethernet bridge, you'll need the bridge - configuration tools; see - for location. Please read the Bridge mini-HOWTO for more - information. - - If you enable iptables support along with the bridge support then you - turn your bridge into a bridging IP firewall. - iptables will then see the IP packets being bridged, so you need to - take this into account when setting up your firewall rules. - Enabling arptables support when bridging will let arptables see - bridged ARP traffic in the arptables FORWARD chain. - - To compile this code as a module, choose M here: the module - will be called bridge. - - If unsure, say N. - menuconfig NETFILTER bool "Network packet filtering (replaces ipchains)" ---help--- @@ -345,9 +292,62 @@ large number of IP-only vcc's. Do not enable this unless you are sure you know what you are doing. +config BRIDGE + tristate "802.1d Ethernet Bridging" + ---help--- + If you say Y here, then your Linux box will be able to act as an + Ethernet bridge, which means that the different Ethernet segments it + is connected to will appear as one Ethernet to the participants. + Several such bridges can work together to create even larger + networks of Ethernets using the IEEE 802.1 spanning tree algorithm. + As this is a standard, Linux bridges will cooperate properly with + other third party bridge products. + + In order to use the Ethernet bridge, you'll need the bridge + configuration tools; see + for location. Please read the Bridge mini-HOWTO for more + information. + + If you enable iptables support along with the bridge support then you + turn your bridge into a bridging IP firewall. + iptables will then see the IP packets being bridged, so you need to + take this into account when setting up your firewall rules. + Enabling arptables support when bridging will let arptables see + bridged ARP traffic in the arptables FORWARD chain. + + To compile this code as a module, choose M here: the module + will be called bridge. + + If unsure, say N. + config VLAN_8021Q tristate "802.1Q VLAN Support" +config DECNET + tristate "DECnet Support" + ---help--- + The DECnet networking protocol was used in many products made by + Digital (now Compaq). It provides reliable stream and sequenced + packet communications over which run a variety of services similar + to those which run over TCP/IP. + + To find some tools to use with the kernel layer support, please + look at Patrick Caulfield's web site: + . + + More detailed documentation is available in + . + + Be sure to say Y to "/proc file system support" and "Sysctl support" + below when using DECnet, since you will need sysctl support to aid + in configuration at run time. + + The DECnet code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called decnet. + +source "net/decnet/Kconfig" + source "net/llc/Kconfig" config IPX @@ -650,14 +650,6 @@ endmenu -source "drivers/net/Kconfig" - -source "net/ax25/Kconfig" - -source "net/irda/Kconfig" - -source "net/bluetooth/Kconfig" - config NETPOLL def_bool NETCONSOLE @@ -674,4 +666,13 @@ config NET_POLL_CONTROLLER def_bool NETPOLL +source "net/ax25/Kconfig" + +source "net/irda/Kconfig" + +source "net/bluetooth/Kconfig" + +source "drivers/net/Kconfig" + endmenu + diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c --- a/net/appletalk/ddp.c Sun Apr 18 13:42:41 2004 +++ b/net/appletalk/ddp.c Sun Apr 18 13:42:41 2004 @@ -1795,13 +1795,7 @@ break; } case SIOCGSTAMP: - if (!sk) - break; - rc = -ENOENT; - if (!sk->sk_stamp.tv_sec) - break; - rc = copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; + rc = sock_get_timestamp(sk, (struct timeval *)arg); break; /* Routing */ case SIOCADDRT: diff -Nru a/net/atm/ioctl.c b/net/atm/ioctl.c --- a/net/atm/ioctl.c Sun Apr 18 13:42:41 2004 +++ b/net/atm/ioctl.c Sun Apr 18 13:42:41 2004 @@ -76,12 +76,8 @@ goto done; } case SIOCGSTAMP: /* borrowed from IP */ - if (!vcc->sk->sk_stamp.tv_sec) { - error = -ENOENT; - goto done; - } - error = copy_to_user((void *)arg, &vcc->sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; + error = sock_get_timestamp(vcc->sk, (struct timeval *) + arg); goto done; case ATM_SETSC: printk(KERN_WARNING "ATM_SETSC is obsolete\n"); diff -Nru a/net/ax25/Kconfig b/net/ax25/Kconfig --- a/net/ax25/Kconfig Sun Apr 18 13:42:41 2004 +++ b/net/ax25/Kconfig Sun Apr 18 13:42:41 2004 @@ -6,9 +6,8 @@ # Joerg Reuter DL1BKE # 19980129 Moved to net/ax25/Config.in, sourcing device drivers. -menu "Amateur Radio support" - -config HAMRADIO +menuconfig HAMRADIO + depends on NET bool "Amateur Radio support" help If you want to connect your Linux box to an amateur radio, answer Y @@ -106,8 +105,6 @@ depends on HAMRADIO && NET && AX25!=n source "drivers/net/hamradio/Kconfig" - -endmenu endmenu diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c --- a/net/ax25/af_ax25.c Sun Apr 18 13:42:41 2004 +++ b/net/ax25/af_ax25.c Sun Apr 18 13:42:41 2004 @@ -1694,12 +1694,7 @@ case SIOCGSTAMP: if (sk != NULL) { - if (!sk->sk_stamp.tv_sec) { - res = -ENOENT; - break; - } - res = copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; + res = sock_get_timestamp(sk, (struct timeval *)arg); break; } res = -EINVAL; diff -Nru a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig --- a/net/bluetooth/Kconfig Sun Apr 18 13:42:41 2004 +++ b/net/bluetooth/Kconfig Sun Apr 18 13:42:41 2004 @@ -2,10 +2,8 @@ # Bluetooth subsystem configuration # -menu "Bluetooth support" +menuconfig BT depends on NET - -config BT tristate "Bluetooth subsystem support" help Bluetooth is low-cost, low-power, short-range wireless technology. @@ -61,6 +59,4 @@ source "net/bluetooth/cmtp/Kconfig" source "drivers/bluetooth/Kconfig" - -endmenu diff -Nru a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c --- a/net/bluetooth/hci_sock.c Sun Apr 18 13:42:41 2004 +++ b/net/bluetooth/hci_sock.c Sun Apr 18 13:42:41 2004 @@ -61,6 +61,11 @@ /* ----- HCI socket interface ----- */ +static inline int hci_test_bit(int nr, void *addr) +{ + return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31)); +} + /* Security filter */ static struct hci_sec_filter hci_sec_filter = { /* Packet types */ @@ -115,8 +120,8 @@ if (skb->pkt_type == HCI_EVENT_PKT) { register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); - - if (!test_bit(evt, flt->event_mask)) + + if (!hci_test_bit(evt, &flt->event_mask)) continue; if (flt->opcode && ((evt == HCI_EV_CMD_COMPLETE && @@ -399,8 +404,8 @@ u16 ogf = hci_opcode_ogf(opcode); u16 ocf = hci_opcode_ocf(opcode); - if (((ogf > HCI_SFLT_MAX_OGF) || - !test_bit(ocf & HCI_FLT_OCF_BITS, hci_sec_filter.ocf_mask[ogf])) && + if (((ogf > HCI_SFLT_MAX_OGF) || + !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) && !capable(CAP_NET_RAW)) { err = -EPERM; goto drop; diff -Nru a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c --- a/net/bluetooth/rfcomm/tty.c Sun Apr 18 13:42:41 2004 +++ b/net/bluetooth/rfcomm/tty.c Sun Apr 18 13:42:41 2004 @@ -315,7 +315,7 @@ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) return -EPERM; - + if (req.flags & (1 << RFCOMM_REUSE_DLC)) { /* Socket must be connected */ if (sk->sk_state != BT_CONNECTED) @@ -354,11 +354,13 @@ BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!(dev = rfcomm_dev_get(req.dev_id))) return -ENODEV; + + if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) { + rfcomm_dev_put(dev); + return -EPERM; + } if (req.flags & (1 << RFCOMM_HANGUP_NOW)) rfcomm_dlc_close(dev->dlc, 0); diff -Nru a/net/bridge/br.c b/net/bridge/br.c --- a/net/bridge/br.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br.c Sun Apr 18 13:42:40 2004 @@ -20,8 +20,7 @@ #include #include #include -#include -#include + #include "br_private.h" #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) @@ -32,6 +31,8 @@ static int __init br_init(void) { + br_fdb_init(); + #ifdef CONFIG_BRIDGE_NETFILTER if (br_netfilter_init()) return 1; @@ -55,16 +56,18 @@ #endif unregister_netdevice_notifier(&br_device_notifier); brioctl_set(NULL); - br_handle_frame_hook = NULL; + + br_cleanup_bridges(); + + synchronize_net(); #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) br_fdb_get_hook = NULL; br_fdb_put_hook = NULL; #endif - br_cleanup_bridges(); - - synchronize_net(); + br_handle_frame_hook = NULL; + br_fdb_fini(); } EXPORT_SYMBOL(br_should_route_hook); diff -Nru a/net/bridge/br_device.c b/net/bridge/br_device.c --- a/net/bridge/br_device.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_device.c Sun Apr 18 13:42:40 2004 @@ -15,7 +15,6 @@ #include #include -#include #include #include #include "br_private.h" @@ -32,7 +31,7 @@ if (copy_from_user(args, data, 4*sizeof(unsigned long))) return -EFAULT; - return br_ioctl(dev->priv, args[0], args[1], args[2], args[3]); + return br_ioctl_device(dev->priv, args[0], args[1], args[2], args[3]); } static struct net_device_stats *br_dev_get_stats(struct net_device *dev) diff -Nru a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c --- a/net/bridge/br_fdb.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_fdb.c Sun Apr 18 13:42:40 2004 @@ -14,12 +14,31 @@ */ #include +#include #include #include +#include +#include #include #include #include "br_private.h" +static kmem_cache_t *br_fdb_cache; + +void __init br_fdb_init(void) +{ + br_fdb_cache = kmem_cache_create("bridge_fdb_cache", + sizeof(struct net_bridge_fdb_entry), + 0, + SLAB_HWCACHE_ALIGN, NULL, NULL); +} + +void __exit br_fdb_fini(void) +{ + kmem_cache_destroy(br_fdb_cache); +} + + /* if topology_changing then use forward_delay (default 15 sec) * otherwise keep longer (default 5 minutes) */ @@ -35,7 +54,7 @@ && time_before_eq(fdb->ageing_timer + hold_time(br), jiffies); } -static __inline__ void copy_fdb(struct __fdb_entry *ent, +static inline void copy_fdb(struct __fdb_entry *ent, const struct net_bridge_fdb_entry *f) { memset(ent, 0, sizeof(struct __fdb_entry)); @@ -43,7 +62,7 @@ ent->port_no = f->dst?f->dst->port_no:0; ent->is_local = f->is_local; ent->ageing_timer_value = f->is_static ? 0 - : ((jiffies - f->ageing_timer) * USER_HZ) / HZ; + : jiffies_to_clock_t(jiffies - f->ageing_timer); } static __inline__ int br_mac_hash(const unsigned char *mac) @@ -173,7 +192,7 @@ void br_fdb_put(struct net_bridge_fdb_entry *ent) { if (atomic_dec_and_test(&ent->use_count)) - kfree(ent); + kmem_cache_free(br_fdb_cache, ent); } int br_fdb_get_entries(struct net_bridge *br, @@ -220,7 +239,7 @@ /* entry was deleted during copy_to_user */ if (atomic_dec_and_test(&f->use_count)) { - kfree(f); + kmem_cache_free(br_fdb_cache, f); num = -EAGAIN; goto out; } @@ -241,12 +260,16 @@ return num; } -void br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, - const unsigned char *addr, int is_local) +int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, + const unsigned char *addr, int is_local) { struct hlist_node *h; struct net_bridge_fdb_entry *fdb; int hash = br_mac_hash(addr); + int ret = 0; + + if (!is_valid_ether_addr(addr)) + return -EADDRNOTAVAIL; write_lock_bh(&br->hash_lock); hlist_for_each(h, &br->hash[hash]) { @@ -262,6 +285,7 @@ printk(KERN_WARNING "%s: received packet with " " own address as source address\n", source->dev->name); + ret = -EEXIST; goto out; } @@ -275,9 +299,11 @@ } } - fdb = kmalloc(sizeof(*fdb), GFP_ATOMIC); - if (fdb == NULL) + fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); + if (unlikely(fdb == NULL)) { + ret = -ENOMEM; goto out; + } memcpy(fdb->addr.addr, addr, ETH_ALEN); atomic_set(&fdb->use_count, 1); @@ -296,4 +322,6 @@ list_add_tail(&fdb->age_list, &br->age_list); out: write_unlock_bh(&br->hash_lock); + + return ret; } diff -Nru a/net/bridge/br_forward.c b/net/bridge/br_forward.c --- a/net/bridge/br_forward.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_forward.c Sun Apr 18 13:42:40 2004 @@ -15,9 +15,7 @@ #include #include -#include #include -#include #include #include "br_private.h" diff -Nru a/net/bridge/br_if.c b/net/bridge/br_if.c --- a/net/bridge/br_if.c Sun Apr 18 13:42:41 2004 +++ b/net/bridge/br_if.c Sun Apr 18 13:42:41 2004 @@ -14,28 +14,65 @@ */ #include +#include +#include #include -#include -#include #include #include #include #include -#include + #include "br_private.h" +/* + * Determine initial path cost based on speed. + * using recommendations from 802.1d standard + * + * Need to simulate user ioctl because not all device's that support + * ethtool, use ethtool_ops. Also, since driver might sleep need to + * not be holding any locks. + */ static int br_initial_port_cost(struct net_device *dev) { + + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + struct ifreq ifr; + mm_segment_t old_fs; + int err; + + strncpy(ifr.ifr_name, dev->name, IFNAMSIZ); + ifr.ifr_data = (void *) &ecmd; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = dev_ethtool(&ifr); + set_fs(old_fs); + + if (!err) { + switch(ecmd.speed) { + case SPEED_100: + return 19; + case SPEED_1000: + return 4; + case SPEED_10000: + return 2; + case SPEED_10: + return 100; + default: + pr_info("bridge: can't decode speed from %s: %d\n", + dev->name, ecmd.speed); + return 100; + } + } + + /* Old silly heuristics based on name */ if (!strncmp(dev->name, "lec", 3)) return 7; - if (!strncmp(dev->name, "eth", 3)) - return 100; /* FIXME handle 100Mbps */ - if (!strncmp(dev->name, "plip", 4)) return 2500; - return 100; + return 100; /* assume old 10Mbps */ } static void destroy_nbp(void *arg) @@ -126,39 +163,56 @@ return br; } +/* find an available port number */ +static int find_portno(struct net_bridge *br) +{ + int index; + struct net_bridge_port *p; + unsigned long *inuse; + + inuse = kmalloc(BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long), + GFP_ATOMIC); + if (!inuse) + return -ENOMEM; + + memset(inuse, 0, BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long)); + set_bit(0, inuse); /* zero is reserved */ + list_for_each_entry(p, &br->port_list, list) { + set_bit(p->port_no, inuse); + } + index = find_first_zero_bit(inuse, BR_MAX_PORTS); + kfree(inuse); + + return (index >= BR_MAX_PORTS) ? -EXFULL : index; +} + /* called under bridge lock */ -static struct net_bridge_port *new_nbp(struct net_bridge *br, struct net_device *dev) +static struct net_bridge_port *new_nbp(struct net_bridge *br, + struct net_device *dev, + unsigned long cost) { - int i; + int index; struct net_bridge_port *p; + + index = find_portno(br); + if (index < 0) + return ERR_PTR(index); p = kmalloc(sizeof(*p), GFP_ATOMIC); if (p == NULL) - return p; + return ERR_PTR(-ENOMEM); memset(p, 0, sizeof(*p)); p->br = br; + dev_hold(dev); p->dev = dev; - p->path_cost = br_initial_port_cost(dev); - p->priority = 0x80; - - for (i=1;i<255;i++) - if (br_get_port(br, i) == NULL) - break; - - if (i == 255) { - kfree(p); - return NULL; - } - + p->path_cost = cost; + p->priority = 0x8000 >> BR_PORT_BITS; dev->br_port = p; - - p->port_no = i; + p->port_no = index; br_init_port(p); p->state = BR_STATE_DISABLED; - list_add_rcu(&p->list, &br->port_list); - return p; } @@ -203,13 +257,11 @@ return ret; } -/* called under bridge lock */ int br_add_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; - - if (dev->br_port != NULL) - return -EBUSY; + unsigned long cost; + int err = 0; if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER) return -EINVAL; @@ -217,34 +269,48 @@ if (dev->hard_start_xmit == br_dev_xmit) return -ELOOP; - dev_hold(dev); - if ((p = new_nbp(br, dev)) == NULL) { - spin_unlock_bh(&br->lock); - dev_put(dev); - return -EXFULL; - } + cost = br_initial_port_cost(dev); - dev_set_promiscuity(dev, 1); + spin_lock_bh(&br->lock); + if (dev->br_port != NULL) + err = -EBUSY; + + else if (IS_ERR(p = new_nbp(br, dev, cost))) + err = PTR_ERR(p); - br_stp_recalculate_bridge_id(br); - br_fdb_insert(br, p, dev->dev_addr, 1); - if ((br->dev->flags & IFF_UP) && (dev->flags & IFF_UP)) - br_stp_enable_port(p); + else if ((err = br_fdb_insert(br, p, dev->dev_addr, 1))) + destroy_nbp(p); + + else { + dev_set_promiscuity(dev, 1); + + list_add_rcu(&p->list, &br->port_list); + + br_stp_recalculate_bridge_id(br); + if ((br->dev->flags & IFF_UP) && (dev->flags & IFF_UP)) + br_stp_enable_port(p); - return 0; + } + spin_unlock_bh(&br->lock); + return err; } -/* called under bridge lock */ int br_del_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; + int err = 0; - if ((p = dev->br_port) == NULL || p->br != br) - return -EINVAL; + spin_lock_bh(&br->lock); + p = dev->br_port; + if (!p || p->br != br) + err = -EINVAL; + else { + del_nbp(p); + br_stp_recalculate_bridge_id(br); + } + spin_unlock_bh(&br->lock); - del_nbp(p); - br_stp_recalculate_bridge_id(br); - return 0; + return err; } int br_get_bridge_ifindices(int *indices, int num) @@ -262,13 +328,14 @@ return i; } -void br_get_port_ifindices(struct net_bridge *br, int *ifindices) +void br_get_port_ifindices(struct net_bridge *br, int *ifindices, int num) { struct net_bridge_port *p; rcu_read_lock(); list_for_each_entry_rcu(p, &br->port_list, list) { - ifindices[p->port_no] = p->dev->ifindex; + if (p->port_no < num) + ifindices[p->port_no] = p->dev->ifindex; } rcu_read_unlock(); } diff -Nru a/net/bridge/br_input.c b/net/bridge/br_input.c --- a/net/bridge/br_input.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_input.c Sun Apr 18 13:42:40 2004 @@ -16,11 +16,10 @@ #include #include #include -#include #include #include "br_private.h" -unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; +const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; static int br_pass_frame_up_finish(struct sk_buff *skb) { diff -Nru a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c --- a/net/bridge/br_ioctl.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_ioctl.c Sun Apr 18 13:42:40 2004 @@ -15,34 +15,20 @@ #include #include -#include +#include +#include #include #include "br_private.h" -/* import values in USER_HZ */ -static inline unsigned long user_to_ticks(unsigned long utick) -{ - return (utick * HZ) / USER_HZ; -} - -/* export values in USER_HZ */ -static inline unsigned long ticks_to_user(unsigned long tick) -{ - return (tick * USER_HZ) / HZ; -} - /* Report time remaining in user HZ */ static unsigned long timer_residue(const struct timer_list *timer) { - return ticks_to_user(timer_pending(timer) - ? (timer->expires - jiffies) : 0); + return timer_pending(timer) + ? jiffies_to_clock_t(timer->expires - jiffies) : 0; } -static int br_ioctl_device(struct net_bridge *br, - unsigned int cmd, - unsigned long arg0, - unsigned long arg1, - unsigned long arg2) +int br_ioctl_device(struct net_bridge *br, unsigned int cmd, + unsigned long arg0, unsigned long arg1, unsigned long arg2) { if (br == NULL) return -EINVAL; @@ -55,16 +41,17 @@ struct net_device *dev; int ret; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + dev = dev_get_by_index(arg0); if (dev == NULL) return -EINVAL; - spin_lock_bh(&br->lock); if (cmd == BRCTL_ADD_IF) ret = br_add_if(br, dev); else ret = br_del_if(br, dev); - spin_unlock_bh(&br->lock); dev_put(dev); return ret; @@ -79,17 +66,17 @@ memcpy(&b.designated_root, &br->designated_root, 8); memcpy(&b.bridge_id, &br->bridge_id, 8); b.root_path_cost = br->root_path_cost; - b.max_age = ticks_to_user(br->max_age); - b.hello_time = ticks_to_user(br->hello_time); + b.max_age = jiffies_to_clock_t(br->max_age); + b.hello_time = jiffies_to_clock_t(br->hello_time); b.forward_delay = br->forward_delay; b.bridge_max_age = br->bridge_max_age; b.bridge_hello_time = br->bridge_hello_time; - b.bridge_forward_delay = ticks_to_user(br->bridge_forward_delay); + b.bridge_forward_delay = jiffies_to_clock_t(br->bridge_forward_delay); b.topology_change = br->topology_change; b.topology_change_detected = br->topology_change_detected; b.root_port = br->root_port; b.stp_enabled = br->stp_enabled; - b.ageing_time = ticks_to_user(br->ageing_time); + b.ageing_time = jiffies_to_clock_t(br->ageing_time); b.hello_timer_value = timer_residue(&br->hello_timer); b.tcn_timer_value = timer_residue(&br->tcn_timer); b.topology_change_timer_value = timer_residue(&br->topology_change_timer); @@ -104,51 +91,67 @@ case BRCTL_GET_PORT_LIST: { - int *indices; - int ret = 0; + int num, *indices; + + num = arg1; + if (num < 0) + return -EINVAL; + if (num == 0) + num = 256; + if (num > BR_MAX_PORTS) + num = BR_MAX_PORTS; - indices = kmalloc(256*sizeof(int), GFP_KERNEL); + indices = kmalloc(num*sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; - memset(indices, 0, 256*sizeof(int)); + memset(indices, 0, num*sizeof(int)); - br_get_port_ifindices(br, indices); - if (copy_to_user((void *)arg0, indices, 256*sizeof(int))) - ret = -EFAULT; + br_get_port_ifindices(br, indices, num); + if (copy_to_user((void *)arg0, indices, num*sizeof(int))) + num = -EFAULT; kfree(indices); - return ret; + return num; } case BRCTL_SET_BRIDGE_FORWARD_DELAY: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_bh(&br->lock); - br->bridge_forward_delay = user_to_ticks(arg0); + br->bridge_forward_delay = clock_t_to_jiffies(arg0); if (br_is_root_bridge(br)) br->forward_delay = br->bridge_forward_delay; spin_unlock_bh(&br->lock); return 0; case BRCTL_SET_BRIDGE_HELLO_TIME: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_bh(&br->lock); - br->bridge_hello_time = user_to_ticks(arg0); + br->bridge_hello_time = clock_t_to_jiffies(arg0); if (br_is_root_bridge(br)) br->hello_time = br->bridge_hello_time; spin_unlock_bh(&br->lock); return 0; case BRCTL_SET_BRIDGE_MAX_AGE: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_bh(&br->lock); - br->bridge_max_age = user_to_ticks(arg0); + br->bridge_max_age = clock_t_to_jiffies(arg0); if (br_is_root_bridge(br)) br->max_age = br->bridge_max_age; spin_unlock_bh(&br->lock); return 0; case BRCTL_SET_AGEING_TIME: - br->ageing_time = user_to_ticks(arg0); - return 0; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; - case BRCTL_SET_GC_INTERVAL: /* no longer used */ + br->ageing_time = clock_t_to_jiffies(arg0); return 0; case BRCTL_GET_PORT_INFO: @@ -185,10 +188,16 @@ } case BRCTL_SET_BRIDGE_STP_STATE: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + br->stp_enabled = arg0?1:0; return 0; case BRCTL_SET_BRIDGE_PRIORITY: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_bh(&br->lock); br_stp_set_bridge_priority(br, arg0); spin_unlock_bh(&br->lock); @@ -199,6 +208,12 @@ struct net_bridge_port *p; int ret = 0; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (arg1 >= (1<<(16-BR_PORT_BITS))) + return -ERANGE; + spin_lock_bh(&br->lock); if ((p = br_get_port(br, arg0)) == NULL) ret = -EINVAL; @@ -213,6 +228,9 @@ struct net_bridge_port *p; int ret = 0; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_bh(&br->lock); if ((p = br_get_port(br, arg0)) == NULL) ret = -EINVAL; @@ -243,9 +261,6 @@ int *indices; int ret = 0; - if (arg1 > 64) - arg1 = 64; - indices = kmalloc(arg1*sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; @@ -265,6 +280,9 @@ { char buf[IFNAMSIZ]; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (copy_from_user(buf, (void *)arg0, IFNAMSIZ)) return -EFAULT; @@ -285,25 +303,8 @@ { unsigned long i[3]; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(i, (void *)arg, 3*sizeof(unsigned long))) return -EFAULT; return br_ioctl_deviceless(i[0], i[1], i[2]); -} - -int br_ioctl(struct net_bridge *br, unsigned int cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2) -{ - int err; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - err = br_ioctl_deviceless(cmd, arg0, arg1); - if (err == -EOPNOTSUPP) - err = br_ioctl_device(br, cmd, arg0, arg1, arg2); - - return err; } diff -Nru a/net/bridge/br_notify.c b/net/bridge/br_notify.c --- a/net/bridge/br_notify.c Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_notify.c Sun Apr 18 13:42:40 2004 @@ -14,7 +14,7 @@ */ #include -#include + #include "br_private.h" static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr); diff -Nru a/net/bridge/br_private.h b/net/bridge/br_private.h --- a/net/bridge/br_private.h Sun Apr 18 13:42:40 2004 +++ b/net/bridge/br_private.h Sun Apr 18 13:42:40 2004 @@ -24,6 +24,9 @@ #define BR_HOLD_TIME (1*HZ) +#define BR_PORT_BITS 10 +#define BR_MAX_PORTS (1< -#include #include -#include + #include "br_private.h" #include "br_private_stp.h" @@ -36,7 +35,7 @@ } /* called under bridge lock */ -struct net_bridge_port *br_get_port(struct net_bridge *br, int port_no) +struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no) { struct net_bridge_port *p; @@ -50,7 +49,7 @@ /* called under bridge lock */ static int br_should_become_root_port(const struct net_bridge_port *p, - int root_port) + u16 root_port) { struct net_bridge *br; struct net_bridge_port *rp; @@ -103,9 +102,7 @@ static void br_root_selection(struct net_bridge *br) { struct net_bridge_port *p; - int root_port; - - root_port = 0; + u16 root_port = 0; list_for_each_entry(p, &br->port_list, list) { if (br_should_become_root_port(p, root_port)) diff -Nru a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c --- a/net/bridge/br_stp_bpdu.c Sun Apr 18 13:42:41 2004 +++ b/net/bridge/br_stp_bpdu.c Sun Apr 18 13:42:41 2004 @@ -14,9 +14,8 @@ */ #include -#include -#include #include + #include "br_private.h" #include "br_private_stp.h" diff -Nru a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c --- a/net/bridge/br_stp_if.c Sun Apr 18 13:42:41 2004 +++ b/net/bridge/br_stp_if.c Sun Apr 18 13:42:41 2004 @@ -14,21 +14,26 @@ */ #include -#include #include -#include + #include "br_private.h" #include "br_private_stp.h" -static inline __u16 br_make_port_id(const struct net_bridge_port *p) + +/* Port id is composed of priority and port number. + * NB: least significant bits of priority are dropped to + * make room for more ports. + */ +static inline port_id br_make_port_id(__u8 priority, __u16 port_no) { - return (p->priority << 8) | p->port_no; + return ((u16)priority << BR_PORT_BITS) + | (port_no & ((1<port_id = br_make_port_id(p); + p->port_id = br_make_port_id(p->priority, p->port_no); br_become_designated_port(p); p->state = BR_STATE_BLOCKING; p->topology_change_ack = 0; @@ -111,7 +116,8 @@ } /* called under bridge lock */ -static void br_stp_change_bridge_id(struct net_bridge *br, unsigned char *addr) +static void br_stp_change_bridge_id(struct net_bridge *br, + const unsigned char *addr) { unsigned char oldaddr[6]; struct net_bridge_port *p; @@ -138,16 +144,14 @@ br_become_root_bridge(br); } -static unsigned char br_mac_zero[6]; +static const unsigned char br_mac_zero[6]; /* called under bridge lock */ void br_stp_recalculate_bridge_id(struct net_bridge *br) { - unsigned char *addr; + const unsigned char *addr = br_mac_zero; struct net_bridge_port *p; - addr = br_mac_zero; - list_for_each_entry(p, &br->port_list, list) { if (addr == br_mac_zero || memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) @@ -160,7 +164,7 @@ } /* called under bridge lock */ -void br_stp_set_bridge_priority(struct net_bridge *br, int newprio) +void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) { struct net_bridge_port *p; int wasroot; @@ -185,17 +189,15 @@ } /* called under bridge lock */ -void br_stp_set_port_priority(struct net_bridge_port *p, int newprio) +void br_stp_set_port_priority(struct net_bridge_port *p, u8 newprio) { - __u16 new_port_id; - - p->priority = newprio & 0xFF; - new_port_id = br_make_port_id(p); + port_id new_port_id = br_make_port_id(newprio, p->port_no); if (br_is_designated_port(p)) p->designated_port = new_port_id; p->port_id = new_port_id; + p->priority = newprio; if (!memcmp(&p->br->bridge_id, &p->designated_bridge, 8) && p->port_id < p->designated_port) { br_become_designated_port(p); @@ -204,7 +206,7 @@ } /* called under bridge lock */ -void br_stp_set_path_cost(struct net_bridge_port *p, int path_cost) +void br_stp_set_path_cost(struct net_bridge_port *p, u32 path_cost) { p->path_cost = path_cost; br_configuration_update(p->br); diff -Nru a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c --- a/net/bridge/br_stp_timer.c Sun Apr 18 13:42:41 2004 +++ b/net/bridge/br_stp_timer.c Sun Apr 18 13:42:41 2004 @@ -14,9 +14,8 @@ */ #include -#include #include -#include + #include "br_private.h" #include "br_private_stp.h" diff -Nru a/net/core/dev.c b/net/core/dev.c --- a/net/core/dev.c Sun Apr 18 13:42:41 2004 +++ b/net/core/dev.c Sun Apr 18 13:42:41 2004 @@ -1125,7 +1125,7 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) { struct packet_type *ptype; - do_gettimeofday(&skb->stamp); + net_timestamp(&skb->stamp); rcu_read_lock(); list_for_each_entry_rcu(ptype, &ptype_all, list) { @@ -1546,9 +1546,9 @@ return NET_RX_DROP; } #endif - + if (!skb->stamp.tv_sec) - do_gettimeofday(&skb->stamp); + net_timestamp(&skb->stamp); /* * The code is rearranged so that the path is the most @@ -1710,7 +1710,7 @@ #endif if (!skb->stamp.tv_sec) - do_gettimeofday(&skb->stamp); + net_timestamp(&skb->stamp); skb_bond(skb); @@ -1903,7 +1903,7 @@ * match. --pb */ -static int dev_ifname(struct ifreq *arg) +static int dev_ifname(struct ifreq __user *arg) { struct net_device *dev; struct ifreq ifr; @@ -1936,7 +1936,7 @@ * Thus we will need a 'compatibility mode'. */ -static int dev_ifconf(char *arg) +static int dev_ifconf(char __user *arg) { struct ifconf ifc; struct net_device *dev; @@ -2539,7 +2539,7 @@ * positive or a negative errno code on error. */ -int dev_ioctl(unsigned int cmd, void *arg) +int dev_ioctl(unsigned int cmd, void __user *arg) { struct ifreq ifr; int ret; @@ -2552,12 +2552,12 @@ if (cmd == SIOCGIFCONF) { rtnl_shlock(); - ret = dev_ifconf((char *) arg); + ret = dev_ifconf((char __user *) arg); rtnl_shunlock(); return ret; } if (cmd == SIOCGIFNAME) - return dev_ifname((struct ifreq *)arg); + return dev_ifname((struct ifreq __user *)arg); if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; diff -Nru a/net/core/dv.c b/net/core/dv.c --- a/net/core/dv.c Sun Apr 18 13:42:41 2004 +++ b/net/core/dv.c Sun Apr 18 13:42:41 2004 @@ -195,7 +195,7 @@ #define DVDBG(a) \ printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a)) -int divert_ioctl(unsigned int cmd, struct divert_cf *arg) +int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg) { struct divert_cf div_cf; struct divert_blk *div_blk; diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c --- a/net/core/ethtool.c Sun Apr 18 13:42:40 2004 +++ b/net/core/ethtool.c Sun Apr 18 13:42:40 2004 @@ -74,7 +74,7 @@ /* Handlers for each ethtool command */ -static int ethtool_get_settings(struct net_device *dev, void *useraddr) +static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) { struct ethtool_cmd cmd = { ETHTOOL_GSET }; int err; @@ -91,7 +91,7 @@ return 0; } -static int ethtool_set_settings(struct net_device *dev, void *useraddr) +static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) { struct ethtool_cmd cmd; @@ -104,7 +104,7 @@ return dev->ethtool_ops->set_settings(dev, &cmd); } -static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) +static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) { struct ethtool_drvinfo info; struct ethtool_ops *ops = dev->ethtool_ops; @@ -130,7 +130,7 @@ return 0; } -static int ethtool_get_regs(struct net_device *dev, char *useraddr) +static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) { struct ethtool_regs regs; struct ethtool_ops *ops = dev->ethtool_ops; @@ -166,7 +166,7 @@ return ret; } -static int ethtool_get_wol(struct net_device *dev, char *useraddr) +static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) { struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; @@ -180,7 +180,7 @@ return 0; } -static int ethtool_set_wol(struct net_device *dev, char *useraddr) +static int ethtool_set_wol(struct net_device *dev, char __user *useraddr) { struct ethtool_wolinfo wol; @@ -193,7 +193,7 @@ return dev->ethtool_ops->set_wol(dev, &wol); } -static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) +static int ethtool_get_msglevel(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GMSGLVL }; @@ -207,7 +207,7 @@ return 0; } -static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) +static int ethtool_set_msglevel(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; @@ -229,7 +229,7 @@ return dev->ethtool_ops->nway_reset(dev); } -static int ethtool_get_link(struct net_device *dev, void *useraddr) +static int ethtool_get_link(struct net_device *dev, void __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GLINK }; @@ -243,7 +243,7 @@ return 0; } -static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) +static int ethtool_get_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; struct ethtool_ops *ops = dev->ethtool_ops; @@ -288,7 +288,7 @@ return ret; } -static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) +static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) { struct ethtool_eeprom eeprom; struct ethtool_ops *ops = dev->ethtool_ops; @@ -329,7 +329,7 @@ return ret; } -static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) +static int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; @@ -343,7 +343,7 @@ return 0; } -static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) +static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce; @@ -356,7 +356,7 @@ return dev->ethtool_ops->set_coalesce(dev, &coalesce); } -static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) +static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) { struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; @@ -370,7 +370,7 @@ return 0; } -static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) +static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr) { struct ethtool_ringparam ringparam; @@ -383,7 +383,7 @@ return dev->ethtool_ops->set_ringparam(dev, &ringparam); } -static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) +static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; @@ -397,7 +397,7 @@ return 0; } -static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) +static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam; @@ -410,7 +410,7 @@ return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); } -static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) +static int ethtool_get_rx_csum(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GRXCSUM }; @@ -424,7 +424,7 @@ return 0; } -static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) +static int ethtool_set_rx_csum(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; @@ -438,7 +438,7 @@ return 0; } -static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) +static int ethtool_get_tx_csum(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GTXCSUM }; @@ -452,7 +452,7 @@ return 0; } -static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) +static int ethtool_set_tx_csum(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; @@ -465,7 +465,7 @@ return dev->ethtool_ops->set_tx_csum(dev, edata.data); } -static int ethtool_get_sg(struct net_device *dev, char *useraddr) +static int ethtool_get_sg(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GSG }; @@ -479,7 +479,7 @@ return 0; } -static int ethtool_set_sg(struct net_device *dev, char *useraddr) +static int ethtool_set_sg(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; @@ -492,7 +492,7 @@ return dev->ethtool_ops->set_sg(dev, edata.data); } -static int ethtool_get_tso(struct net_device *dev, char *useraddr) +static int ethtool_get_tso(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata = { ETHTOOL_GTSO }; @@ -506,7 +506,7 @@ return 0; } -static int ethtool_set_tso(struct net_device *dev, char *useraddr) +static int ethtool_set_tso(struct net_device *dev, char __user *useraddr) { struct ethtool_value edata; @@ -519,7 +519,7 @@ return dev->ethtool_ops->set_tso(dev, edata.data); } -static int ethtool_self_test(struct net_device *dev, char *useraddr) +static int ethtool_self_test(struct net_device *dev, char __user *useraddr) { struct ethtool_test test; struct ethtool_ops *ops = dev->ethtool_ops; @@ -552,7 +552,7 @@ return ret; } -static int ethtool_get_strings(struct net_device *dev, void *useraddr) +static int ethtool_get_strings(struct net_device *dev, void __user *useraddr) { struct ethtool_gstrings gstrings; struct ethtool_ops *ops = dev->ethtool_ops; @@ -599,7 +599,7 @@ return ret; } -static int ethtool_phys_id(struct net_device *dev, void *useraddr) +static int ethtool_phys_id(struct net_device *dev, void __user *useraddr) { struct ethtool_value id; @@ -612,7 +612,7 @@ return dev->ethtool_ops->phys_id(dev, id.data); } -static int ethtool_get_stats(struct net_device *dev, void *useraddr) +static int ethtool_get_stats(struct net_device *dev, void __user *useraddr) { struct ethtool_stats stats; struct ethtool_ops *ops = dev->ethtool_ops; @@ -650,7 +650,7 @@ int dev_ethtool(struct ifreq *ifr) { struct net_device *dev = __dev_get_by_name(ifr->ifr_name); - void *useraddr = (void *) ifr->ifr_data; + void __user *useraddr = (void __user *) ifr->ifr_data; u32 ethcmd; /* @@ -740,6 +740,7 @@ return -EOPNOTSUPP; } +EXPORT_SYMBOL(dev_ethtool); EXPORT_SYMBOL(ethtool_op_get_link); EXPORT_SYMBOL(ethtool_op_get_sg); EXPORT_SYMBOL(ethtool_op_get_tso); diff -Nru a/net/core/neighbour.c b/net/core/neighbour.c --- a/net/core/neighbour.c Sun Apr 18 13:42:40 2004 +++ b/net/core/neighbour.c Sun Apr 18 13:42:40 2004 @@ -1094,7 +1094,7 @@ kfree_skb(skb); return; } - skb->stamp.tv_sec = 0; + skb->stamp.tv_sec = LOCALLY_ENQUEUED; skb->stamp.tv_usec = now + sched_next; spin_lock(&tbl->proxy_queue.lock); diff -Nru a/net/core/netfilter.c b/net/core/netfilter.c --- a/net/core/netfilter.c Sun Apr 18 13:42:41 2004 +++ b/net/core/netfilter.c Sun Apr 18 13:42:41 2004 @@ -8,8 +8,10 @@ * * February 2000: Modified by James Morris to have 1 queue per protocol. * 15-Mar-2000: Added NF_REPEAT --RR. + * 08-May-2003: Internal logging interface added by Jozsef Kadlecsik. */ #include +#include #include #include #include @@ -741,6 +743,72 @@ EXPORT_SYMBOL(skb_ip_make_writable); #endif /*CONFIG_INET*/ +/* Internal logging interface, which relies on the real + LOG target modules */ + +#define NF_LOG_PREFIXLEN 128 + +static nf_logfn *nf_logging[NPROTO]; /* = NULL */ +static int reported = 0; +static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED; + +int nf_log_register(int pf, nf_logfn *logfn) +{ + int ret = -EBUSY; + + /* Any setup of logging members must be done before + * substituting pointer. */ + smp_wmb(); + spin_lock(&nf_log_lock); + if (!nf_logging[pf]) { + nf_logging[pf] = logfn; + ret = 0; + } + spin_unlock(&nf_log_lock); + return ret; +} + +void nf_log_unregister(int pf, nf_logfn *logfn) +{ + spin_lock(&nf_log_lock); + if (nf_logging[pf] == logfn) + nf_logging[pf] = NULL; + spin_unlock(&nf_log_lock); + + /* Give time to concurrent readers. */ + synchronize_net(); +} + +void nf_log_packet(int pf, + unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *fmt, ...) +{ + va_list args; + char prefix[NF_LOG_PREFIXLEN]; + nf_logfn *logfn; + + rcu_read_lock(); + logfn = nf_logging[pf]; + if (logfn) { + va_start(args, fmt); + vsnprintf(prefix, sizeof(prefix), fmt, args); + va_end(args); + /* We must read logging before nf_logfn[pf] */ + smp_read_barrier_depends(); + logfn(hooknum, skb, in, out, prefix); + } else if (!reported) { + printk(KERN_WARNING "nf_log_packet: can\'t log yet, " + "no backend logging module loaded in!\n"); + reported++; + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(nf_log_register); +EXPORT_SYMBOL(nf_log_unregister); +EXPORT_SYMBOL(nf_log_packet); /* This does not belong here, but ipt_REJECT needs it if connection tracking in use: without this, connection may not be in hash table, diff -Nru a/net/core/netpoll.c b/net/core/netpoll.c --- a/net/core/netpoll.c Sun Apr 18 13:42:41 2004 +++ b/net/core/netpoll.c Sun Apr 18 13:42:41 2004 @@ -163,21 +163,15 @@ spin_lock(&np->dev->xmit_lock); np->dev->xmit_lock_owner = smp_processor_id(); - if (netif_queue_stopped(np->dev)) { - np->dev->xmit_lock_owner = -1; - spin_unlock(&np->dev->xmit_lock); - - netpoll_poll(np); - goto repeat; - } - status = np->dev->hard_start_xmit(skb, np->dev); np->dev->xmit_lock_owner = -1; spin_unlock(&np->dev->xmit_lock); /* transmit busy */ - if(status) + if(status) { + netpoll_poll(np); goto repeat; + } } void netpoll_send_udp(struct netpoll *np, const char *msg, int len) @@ -231,9 +225,8 @@ static void arp_reply(struct sk_buff *skb) { - struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr; struct arphdr *arp; - unsigned char *arp_ptr, *sha, *tha; + unsigned char *arp_ptr; int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; u32 sip, tip; struct sk_buff *send_skb; @@ -253,7 +246,7 @@ if (!np) return; /* No arp on this interface */ - if (!in_dev || skb->dev->flags & IFF_NOARP) + if (skb->dev->flags & IFF_NOARP) return; if (!pskb_may_pull(skb, (sizeof(struct arphdr) + @@ -270,21 +263,15 @@ arp->ar_op != htons(ARPOP_REQUEST)) return; - arp_ptr= (unsigned char *)(arp+1); - sha = arp_ptr; - arp_ptr += skb->dev->addr_len; + arp_ptr = (unsigned char *)(arp+1) + skb->dev->addr_len; memcpy(&sip, arp_ptr, 4); - arp_ptr += 4; - tha = arp_ptr; - arp_ptr += skb->dev->addr_len; + arp_ptr += 4 + skb->dev->addr_len; memcpy(&tip, arp_ptr, 4); /* Should we ignore arp? */ - if (tip != in_dev->ifa_list->ifa_address || - LOOPBACK(tip) || MULTICAST(tip)) + if (tip != htonl(np->local_ip) || LOOPBACK(tip) || MULTICAST(tip)) return; - size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4); send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev), LL_RESERVED_SPACE(np->dev)); @@ -325,7 +312,7 @@ arp_ptr += np->dev->addr_len; memcpy(arp_ptr, &tip, 4); arp_ptr += 4; - memcpy(arp_ptr, np->local_mac, np->dev->addr_len); + memcpy(arp_ptr, np->remote_mac, np->dev->addr_len); arp_ptr += np->dev->addr_len; memcpy(arp_ptr, &sip, 4); diff -Nru a/net/core/sock.c b/net/core/sock.c --- a/net/core/sock.c Sun Apr 18 13:42:41 2004 +++ b/net/core/sock.c Sun Apr 18 13:42:41 2004 @@ -328,6 +328,8 @@ case SO_TIMESTAMP: sk->sk_rcvtstamp = valbool; + if (valbool) + sock_enable_timestamp(sk); break; case SO_RCVLOWAT: @@ -642,6 +644,8 @@ sk->sk_filter = NULL; } + sock_disable_timestamp(sk); + if (atomic_read(&sk->sk_omem_alloc)) printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); @@ -973,13 +977,13 @@ } int sock_no_setsockopt(struct socket *sock, int level, int optname, - char *optval, int optlen) + char __user *optval, int optlen) { return -EOPNOTSUPP; } int sock_no_getsockopt(struct socket *sock, int level, int optname, - char *optval, int *optlen) + char __user *optval, int __user *optlen) { return -EOPNOTSUPP; } @@ -1135,10 +1139,13 @@ sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; sk->sk_owner = NULL; + sk->sk_stamp.tv_sec = -1L; + sk->sk_stamp.tv_usec = -1L; + atomic_set(&sk->sk_refcnt, 1); } -void lock_sock(struct sock *sk) +void fastcall lock_sock(struct sock *sk) { might_sleep(); spin_lock_bh(&(sk->sk_lock.slock)); @@ -1150,7 +1157,7 @@ EXPORT_SYMBOL(lock_sock); -void release_sock(struct sock *sk) +void fastcall release_sock(struct sock *sk) { spin_lock_bh(&(sk->sk_lock.slock)); if (sk->sk_backlog.tail) @@ -1160,8 +1167,41 @@ wake_up(&(sk->sk_lock.wq)); spin_unlock_bh(&(sk->sk_lock.slock)); } - EXPORT_SYMBOL(release_sock); + +/* When > 0 there are consumers of rx skb time stamps */ +atomic_t netstamp_needed = ATOMIC_INIT(0); + +int sock_get_timestamp(struct sock *sk, struct timeval *userstamp) +{ + if (!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk); + if (sk->sk_stamp.tv_sec == -1) + return -ENOENT; + if (sk->sk_stamp.tv_sec == 0) + do_gettimeofday(&sk->sk_stamp); + return copy_to_user(userstamp, &sk->sk_stamp, sizeof(struct timeval)) ? + -EFAULT : 0; +} +EXPORT_SYMBOL(sock_get_timestamp); + +void sock_enable_timestamp(struct sock *sk) +{ + if (!sock_flag(sk, SOCK_TIMESTAMP)) { + sock_set_flag(sk, SOCK_TIMESTAMP); + atomic_inc(&netstamp_needed); + } +} +EXPORT_SYMBOL(sock_enable_timestamp); + +void sock_disable_timestamp(struct sock *sk) +{ + if (sock_flag(sk, SOCK_TIMESTAMP)) { + sock_reset_flag(sk, SOCK_TIMESTAMP); + atomic_dec(&netstamp_needed); + } +} +EXPORT_SYMBOL(sock_disable_timestamp); EXPORT_SYMBOL(__lock_sock); EXPORT_SYMBOL(__release_sock); diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c --- a/net/econet/af_econet.c Sun Apr 18 13:42:41 2004 +++ b/net/econet/af_econet.c Sun Apr 18 13:42:41 2004 @@ -665,10 +665,8 @@ switch(cmd) { case SIOCGSTAMP: - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - return copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; + return sock_get_timestamp(sk,(struct timeval *)arg); + case SIOCSIFADDR: case SIOCGIFADDR: return ec_dev_ioctl(sock, cmd, (void *)arg); diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c --- a/net/ipv4/af_inet.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/af_inet.c Sun Apr 18 13:42:40 2004 @@ -843,11 +843,7 @@ switch (cmd) { case SIOCGSTAMP: - if (!sk->sk_stamp.tv_sec) - err = -ENOENT; - else if (copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval))) - err = -EFAULT; + err = sock_get_timestamp(sk, (struct timeval *)arg); break; case SIOCADDRT: case SIOCDELRT: diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c --- a/net/ipv4/arp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/arp.c Sun Apr 18 13:42:41 2004 @@ -860,7 +860,7 @@ if (n) neigh_release(n); - if (skb->stamp.tv_sec == 0 || + if (skb->stamp.tv_sec == LOCALLY_ENQUEUED || skb->pkt_type == PACKET_HOST || in_dev->arp_parms->proxy_delay == 0) { arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); diff -Nru a/net/ipv4/esp4.c b/net/ipv4/esp4.c --- a/net/ipv4/esp4.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/esp4.c Sun Apr 18 13:42:41 2004 @@ -31,6 +31,7 @@ struct esp_data *esp; struct sk_buff *trailer; struct udphdr *uh = NULL; + u32 *udpdata32; struct xfrm_encap_tmpl *encap = NULL; int blksize; int clen; @@ -97,6 +98,14 @@ esph = (struct ip_esp_hdr*)(uh+1); top_iph->protocol = IPPROTO_UDP; break; + case UDP_ENCAP_ESPINUDP_NON_IKE: + uh = (struct udphdr*) esph; + udpdata32 = (u32*)(uh+1); + udpdata32[0] = udpdata32[1] = 0; + esph = (struct ip_esp_hdr*)(udpdata32+2); + alen += 2; + top_iph->protocol = IPPROTO_UDP; + break; default: printk(KERN_INFO "esp_output(): Unhandled encap: %u\n", @@ -132,6 +141,14 @@ esph = (struct ip_esp_hdr*)(uh+1); top_iph->protocol = IPPROTO_UDP; break; + case UDP_ENCAP_ESPINUDP_NON_IKE: + uh = (struct udphdr*) esph; + udpdata32 = (u32*)(uh+1); + udpdata32[0] = udpdata32[1] = 0; + esph = (struct ip_esp_hdr*)(udpdata32+2); + alen += 2; + top_iph->protocol = IPPROTO_UDP; + break; default: printk(KERN_INFO "esp_output(): Unhandled encap: %u\n", @@ -294,6 +311,7 @@ switch (decap->decap_type) { case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: if ((void*)uh == (void*)esph) { printk(KERN_DEBUG @@ -354,6 +372,7 @@ switch (encap->encap_type) { case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: /* * 1) if the NAT-T peer's IP or port changed then * advertize the change to the keying daemon. @@ -428,8 +447,8 @@ x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET); if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n", - ntohl(esph->spi), ntohl(iph->daddr)); + NETDEBUG(printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%08x\n", + ntohl(esph->spi), ntohl(iph->daddr))); xfrm_state_put(x); } @@ -492,10 +511,10 @@ if (aalg_desc->uinfo.auth.icv_fullbits/8 != crypto_tfm_alg_digestsize(esp->auth.tfm)) { - printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", + NETDEBUG(printk(KERN_INFO "ESP: %s digestsize %u != %hu\n", x->aalg->alg_name, crypto_tfm_alg_digestsize(esp->auth.tfm), - aalg_desc->uinfo.auth.icv_fullbits/8); + aalg_desc->uinfo.auth.icv_fullbits/8)); goto error; } @@ -533,6 +552,9 @@ switch (encap->encap_type) { case UDP_ENCAP_ESPINUDP: x->props.header_len += sizeof(struct udphdr); + break; + case UDP_ENCAP_ESPINUDP_NON_IKE: + x->props.header_len += sizeof(struct udphdr) + 2 * sizeof(u32); break; default: printk (KERN_INFO diff -Nru a/net/ipv4/icmp.c b/net/ipv4/icmp.c --- a/net/ipv4/icmp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/icmp.c Sun Apr 18 13:42:41 2004 @@ -620,11 +620,11 @@ break; case ICMP_FRAG_NEEDED: if (ipv4_config.no_pmtu_disc) { - if (net_ratelimit()) + LIMIT_NETDEBUG( printk(KERN_INFO "ICMP: %u.%u.%u.%u: " "fragmentation needed " "and DF set.\n", - NIPQUAD(iph->daddr)); + NIPQUAD(iph->daddr))); } else { info = ip_rt_frag_needed(iph, ntohs(icmph->un.frag.mtu)); @@ -633,10 +633,10 @@ } break; case ICMP_SR_FAILED: - if (net_ratelimit()) + LIMIT_NETDEBUG( printk(KERN_INFO "ICMP: %u.%u.%u.%u: Source " "Route Failed.\n", - NIPQUAD(iph->daddr)); + NIPQUAD(iph->daddr))); break; default: break; diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c --- a/net/ipv4/igmp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/igmp.c Sun Apr 18 13:42:41 2004 @@ -2223,7 +2223,9 @@ struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); char *querier; #ifdef CONFIG_IP_MULTICAST - querier = IGMP_V1_SEEN(state->in_dev) ? "V1" : "V2"; + querier = IGMP_V1_SEEN(state->in_dev) ? "V1" : + IGMP_V2_SEEN(state->in_dev) ? "V2" : + "V3"; #else querier = "NONE"; #endif @@ -2236,7 +2238,9 @@ seq_printf(seq, "\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n", im->multiaddr, im->users, - im->tm_running, jiffies_to_clock_t(im->timer.expires-jiffies), im->reporter); + im->tm_running, im->tm_running ? + jiffies_to_clock_t(im->timer.expires-jiffies) : 0, + im->reporter); } return 0; } diff -Nru a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c --- a/net/ipv4/ipcomp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/ipcomp.c Sun Apr 18 13:42:41 2004 @@ -258,8 +258,8 @@ spi, IPPROTO_COMP, AF_INET); if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%u.%u.%u.%u\n", - spi, NIPQUAD(iph->daddr)); + NETDEBUG(printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%u.%u.%u.%u\n", + spi, NIPQUAD(iph->daddr))); xfrm_state_put(x); } diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig --- a/net/ipv4/netfilter/Kconfig Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/Kconfig Sun Apr 18 13:42:41 2004 @@ -579,5 +579,29 @@ To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_NOTRACK + tristate 'NOTRACK target support' + depends on IP_NF_RAW + help + The NOTRACK target allows a select rule to specify + which packets *not* to enter the conntrack/NAT + subsystem with all the consequences (no ICMP error tracking, + no protocol helpers for the selected packets). + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_RAW + tristate 'raw table support (required for NOTRACK/TRACE)' + depends on IP_NF_IPTABLES + help + This option adds a `raw' table to iptables. This table is the very + first in the netfilter framework and hooks in at the PREROUTING + and OUTPUT chains. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + help + endmenu diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile --- a/net/ipv4/netfilter/Makefile Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/Makefile Sun Apr 18 13:42:40 2004 @@ -38,6 +38,7 @@ obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o +obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o # matches obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o @@ -81,6 +82,7 @@ obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff -Nru a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c --- a/net/ipv4/netfilter/ip_conntrack_amanda.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c Sun Apr 18 13:42:41 2004 @@ -46,10 +46,11 @@ static int help(struct sk_buff *skb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { - struct ip_conntrack_expect exp; + struct ip_conntrack_expect *exp; struct ip_ct_amanda_expect *exp_amanda_info; char *data, *data_limit, *tmp; unsigned int dataoff, i; + u_int16_t port, len; /* Only look at packets from the Amanda server */ if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) @@ -79,33 +80,40 @@ goto out; data += strlen("CONNECT "); - memset(&exp, 0, sizeof(exp)); - exp.tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; - exp.tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; - exp.tuple.dst.protonum = IPPROTO_TCP; - exp.mask.src.ip = 0xFFFFFFFF; - exp.mask.dst.ip = 0xFFFFFFFF; - exp.mask.dst.protonum = 0xFFFF; - exp.mask.dst.u.tcp.port = 0xFFFF; - /* Only search first line. */ if ((tmp = strchr(data, '\n'))) *tmp = '\0'; - exp_amanda_info = &exp.help.exp_amanda_info; for (i = 0; i < ARRAY_SIZE(conns); i++) { char *match = strstr(data, conns[i]); if (!match) continue; tmp = data = match + strlen(conns[i]); - exp_amanda_info->offset = data - amanda_buffer; - exp_amanda_info->port = simple_strtoul(data, &data, 10); - exp_amanda_info->len = data - tmp; - if (exp_amanda_info->port == 0 || exp_amanda_info->len > 5) + port = simple_strtoul(data, &data, 10); + len = data - tmp; + if (port == 0 || len > 5) break; - exp.tuple.dst.u.tcp.port = htons(exp_amanda_info->port); - ip_conntrack_expect_related(ct, &exp); + exp = ip_conntrack_expect_alloc(); + if (exp == NULL) + goto out; + + exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; + exp->tuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; + exp->tuple.dst.protonum = IPPROTO_TCP; + exp->mask.src.ip = 0xFFFFFFFF; + exp->mask.dst.ip = 0xFFFFFFFF; + exp->mask.dst.protonum = 0xFFFF; + exp->mask.dst.u.tcp.port = 0xFFFF; + + exp_amanda_info = &exp->help.exp_amanda_info; + exp_amanda_info->offset = data - amanda_buffer; + exp_amanda_info->port = port; + exp_amanda_info->len = len; + + exp->tuple.dst.u.tcp.port = htons(port); + + ip_conntrack_expect_related(exp, ct); } out: diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c --- a/net/ipv4/netfilter/ip_conntrack_core.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/ip_conntrack_core.c Sun Apr 18 13:42:40 2004 @@ -67,6 +67,7 @@ static atomic_t ip_conntrack_count = ATOMIC_INIT(0); struct list_head *ip_conntrack_hash; static kmem_cache_t *ip_conntrack_cachep; +struct ip_conntrack ip_conntrack_untracked; extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; @@ -794,6 +795,15 @@ int set_reply; int ret; + /* Never happen */ + if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) { + if (net_ratelimit()) { + printk(KERN_ERR "ip_conntrack_in: Frag of proto %u (hook=%u)\n", + (*pskb)->nh.iph->protocol, hooknum); + } + return NF_DROP; + } + /* FIXME: Do this right please. --RR */ (*pskb)->nfcache |= NFC_UNKNOWN; @@ -812,18 +822,10 @@ } #endif - /* Previously seen (loopback)? Ignore. Do this before - fragment check. */ + /* Previously seen (loopback or untracked)? Ignore. */ if ((*pskb)->nfct) return NF_ACCEPT; - /* Gather fragments. */ - if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { - *pskb = ip_ct_gather_frags(*pskb); - if (!*pskb) - return NF_STOLEN; - } - proto = ip_ct_find_proto((*pskb)->nh.iph->protocol); /* It may be an icmp error... */ @@ -917,11 +919,55 @@ WRITE_UNLOCK(&ip_conntrack_lock); } +struct ip_conntrack_expect * +ip_conntrack_expect_alloc() +{ + struct ip_conntrack_expect *new; + + new = (struct ip_conntrack_expect *) + kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC); + if (!new) { + DEBUGP("expect_related: OOM allocating expect\n"); + return NULL; + } + + /* tuple_cmp compares whole union, we have to initialized cleanly */ + memset(new, 0, sizeof(struct ip_conntrack_expect)); + + return new; +} + +static void +ip_conntrack_expect_insert(struct ip_conntrack_expect *new, + struct ip_conntrack *related_to) +{ + DEBUGP("new expectation %p of conntrack %p\n", new, related_to); + new->expectant = related_to; + new->sibling = NULL; + atomic_set(&new->use, 1); + + /* add to expected list for this connection */ + list_add(&new->expected_list, &related_to->sibling_list); + /* add to global list of expectations */ + + list_prepend(&ip_conntrack_expect_list, &new->list); + /* add and start timer if required */ + if (related_to->helper->timeout) { + init_timer(&new->timeout); + new->timeout.data = (unsigned long)new; + new->timeout.function = expectation_timed_out; + new->timeout.expires = jiffies + + related_to->helper->timeout * HZ; + add_timer(&new->timeout); + } + related_to->expecting++; +} + /* Add a related connection. */ -int ip_conntrack_expect_related(struct ip_conntrack *related_to, - struct ip_conntrack_expect *expect) +int ip_conntrack_expect_related(struct ip_conntrack_expect *expect, + struct ip_conntrack *related_to) { - struct ip_conntrack_expect *old, *new; + struct ip_conntrack_expect *old; int ret = 0; WRITE_LOCK(&ip_conntrack_lock); @@ -943,7 +989,7 @@ if (related_to->helper->timeout) { if (!del_timer(&old->timeout)) { /* expectation is dying. Fall through */ - old = NULL; + goto out; } else { old->timeout.expires = jiffies + related_to->helper->timeout * HZ; @@ -951,10 +997,10 @@ } } - if (old) { - WRITE_UNLOCK(&ip_conntrack_lock); - return -EEXIST; - } + WRITE_UNLOCK(&ip_conntrack_lock); + kfree(expect); + return -EEXIST; + } else if (related_to->helper->max_expected && related_to->expecting >= related_to->helper->max_expected) { struct list_head *cur_item; @@ -971,6 +1017,7 @@ related_to->helper->name, NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); + kfree(expect); return -EPERM; } DEBUGP("ip_conntrack: max number of expected " @@ -1010,37 +1057,12 @@ &expect->mask)) { WRITE_UNLOCK(&ip_conntrack_lock); DEBUGP("expect_related: busy!\n"); + + kfree(expect); return -EBUSY; } - - new = (struct ip_conntrack_expect *) - kmalloc(sizeof(struct ip_conntrack_expect), GFP_ATOMIC); - if (!new) { - WRITE_UNLOCK(&ip_conntrack_lock); - DEBUGP("expect_relaed: OOM allocating expect\n"); - return -ENOMEM; - } - - DEBUGP("new expectation %p of conntrack %p\n", new, related_to); - memcpy(new, expect, sizeof(*expect)); - new->expectant = related_to; - new->sibling = NULL; - atomic_set(&new->use, 1); - - /* add to expected list for this connection */ - list_add(&new->expected_list, &related_to->sibling_list); - /* add to global list of expectations */ - list_prepend(&ip_conntrack_expect_list, &new->list); - /* add and start timer if required */ - if (related_to->helper->timeout) { - init_timer(&new->timeout); - new->timeout.data = (unsigned long)new; - new->timeout.function = expectation_timed_out; - new->timeout.expires = jiffies + - related_to->helper->timeout * HZ; - add_timer(&new->timeout); - } - related_to->expecting++; + +out: ip_conntrack_expect_insert(expect, related_to); WRITE_UNLOCK(&ip_conntrack_lock); @@ -1158,18 +1180,18 @@ { IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); - WRITE_LOCK(&ip_conntrack_lock); /* If not in hash table, timer will not be active yet */ if (!is_confirmed(ct)) ct->timeout.expires = extra_jiffies; else { + WRITE_LOCK(&ip_conntrack_lock); /* Need del_timer for race avoidance (may already be dying). */ if (del_timer(&ct->timeout)) { ct->timeout.expires = jiffies + extra_jiffies; add_timer(&ct->timeout); } + WRITE_UNLOCK(&ip_conntrack_lock); } - WRITE_UNLOCK(&ip_conntrack_lock); } /* Returns new sk_buff, or NULL */ @@ -1422,6 +1444,18 @@ /* For use by ipt_REJECT */ ip_ct_attach = ip_conntrack_attach; + + /* Set up fake conntrack: + - to never be deleted, not in any hashes */ + atomic_set(&ip_conntrack_untracked.ct_general.use, 1); + /* - and look it like as a confirmed connection */ + set_bit(IPS_CONFIRMED_BIT, &ip_conntrack_untracked.status); + /* - and prepare the ctinfo field for REJECT & NAT. */ + ip_conntrack_untracked.infos[IP_CT_NEW].master = + ip_conntrack_untracked.infos[IP_CT_RELATED].master = + ip_conntrack_untracked.infos[IP_CT_RELATED + IP_CT_IS_REPLY].master = + &ip_conntrack_untracked.ct_general; + return ret; err_free_hash: diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c --- a/net/ipv4/netfilter/ip_conntrack_ftp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c Sun Apr 18 13:42:41 2004 @@ -256,8 +256,8 @@ int dir = CTINFO2DIR(ctinfo); unsigned int matchlen, matchoff; struct ip_ct_ftp_master *ct_ftp_info = &ct->help.ct_ftp_info; - struct ip_conntrack_expect expect, *exp = &expect; - struct ip_ct_ftp_expect *exp_ftp_info = &exp->help.exp_ftp_info; + struct ip_conntrack_expect *exp; + struct ip_ct_ftp_expect *exp_ftp_info; unsigned int i; int found = 0; @@ -346,8 +346,15 @@ DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n", (int)matchlen, data + matchoff, matchlen, ntohl(tcph.seq) + matchoff); - - memset(&expect, 0, sizeof(expect)); + + /* Allocate expectation which will be inserted */ + exp = ip_conntrack_expect_alloc(); + if (exp == NULL) { + ret = NF_ACCEPT; + goto out; + } + + exp_ftp_info = &exp->help.exp_ftp_info; /* Update the ftp info */ if (htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]) @@ -389,7 +396,7 @@ exp->expectfn = NULL; /* Ignore failure; should only happen with NAT */ - ip_conntrack_expect_related(ct, &expect); + ip_conntrack_expect_related(exp, ct); ret = NF_ACCEPT; out: UNLOCK_BH(&ip_ftp_lock); diff -Nru a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c --- a/net/ipv4/netfilter/ip_conntrack_irc.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ip_conntrack_irc.c Sun Apr 18 13:42:41 2004 @@ -60,8 +60,8 @@ struct module *ip_conntrack_irc = THIS_MODULE; #if 0 -#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__ \ - ":" format, ## args) +#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \ + __FILE__, __FUNCTION__ , ## args) #else #define DEBUGP(format, args...) #endif @@ -106,8 +106,8 @@ struct tcphdr tcph; char *data, *data_limit; int dir = CTINFO2DIR(ctinfo); - struct ip_conntrack_expect expect, *exp = &expect; - struct ip_ct_irc_expect *exp_irc_info = &exp->help.exp_irc_info; + struct ip_conntrack_expect *exp; + struct ip_ct_irc_expect *exp_irc_info = NULL; u_int32_t dcc_ip; u_int16_t dcc_port; @@ -190,8 +190,12 @@ continue; } - - memset(&expect, 0, sizeof(expect)); + + exp = ip_conntrack_expect_alloc(); + if (exp == NULL) + goto out; + + exp_irc_info = &exp->help.exp_irc_info; /* save position of address in dcc string, * necessary for NAT */ @@ -218,7 +222,7 @@ NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port)); - ip_conntrack_expect_related(ct, &expect); + ip_conntrack_expect_related(exp, ct); goto out; } /* for .. NUM_DCCPROTO */ diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Sun Apr 18 13:42:41 2004 @@ -178,6 +178,16 @@ if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &tcph, sizeof(tcph)) != 0) return -1; + /* If only reply is a RST, we can consider ourselves not to + have an established connection: this is a fairly common + problem case, so we can delete the conntrack + immediately. --RR */ + if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && tcph.rst) { + if (del_timer(&conntrack->timeout)) + conntrack->timeout.function((unsigned long)conntrack); + return NF_ACCEPT; + } + WRITE_LOCK(&tcp_lock); oldtcpstate = conntrack->proto.tcp.state; newconntrack @@ -199,29 +209,21 @@ /* Poor man's window tracking: record SYN/ACK for handshake check */ if (oldtcpstate == TCP_CONNTRACK_SYN_SENT && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY - && tcph.syn && tcph.ack) + && tcph.syn && tcph.ack) { conntrack->proto.tcp.handshake_ack = htonl(ntohl(tcph.seq) + 1); + goto out; + } - /* If only reply is a RST, we can consider ourselves not to - have an established connection: this is a fairly common - problem case, so we can delete the conntrack - immediately. --RR */ - if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) && tcph.rst) { - WRITE_UNLOCK(&tcp_lock); - if (del_timer(&conntrack->timeout)) - conntrack->timeout.function((unsigned long)conntrack); - } else { - /* Set ASSURED if we see see valid ack in ESTABLISHED after SYN_RECV */ - if (oldtcpstate == TCP_CONNTRACK_SYN_RECV - && CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL - && tcph.ack && !tcph.syn - && tcph.ack_seq == conntrack->proto.tcp.handshake_ack) - set_bit(IPS_ASSURED_BIT, &conntrack->status); + /* Set ASSURED if we see valid ack in ESTABLISHED after SYN_RECV */ + if (oldtcpstate == TCP_CONNTRACK_SYN_RECV + && CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL + && tcph.ack && !tcph.syn + && tcph.ack_seq == conntrack->proto.tcp.handshake_ack) + set_bit(IPS_ASSURED_BIT, &conntrack->status); - WRITE_UNLOCK(&tcp_lock); - ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]); - } +out: WRITE_UNLOCK(&tcp_lock); + ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]); return NF_ACCEPT; } diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c --- a/net/ipv4/netfilter/ip_conntrack_standalone.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c Sun Apr 18 13:42:41 2004 @@ -194,6 +194,26 @@ return ip_conntrack_confirm(*pskb); } +static unsigned int ip_conntrack_defrag(unsigned int hooknum, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + /* Previously seen (loopback)? Ignore. Do this before + fragment check. */ + if ((*pskb)->nfct) + return NF_ACCEPT; + + /* Gather fragments. */ + if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { + *pskb = ip_ct_gather_frags(*pskb); + if (!*pskb) + return NF_STOLEN; + } + return NF_ACCEPT; +} + static unsigned int ip_refrag(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, @@ -236,6 +256,14 @@ /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ +static struct nf_hook_ops ip_conntrack_defrag_ops = { + .hook = ip_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, +}; + static struct nf_hook_ops ip_conntrack_in_ops = { .hook = ip_conntrack_in, .owner = THIS_MODULE, @@ -244,6 +272,14 @@ .priority = NF_IP_PRI_CONNTRACK, }; +static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = { + .hook = ip_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, +}; + static struct nf_hook_ops ip_conntrack_local_out_ops = { .hook = ip_conntrack_local, .owner = THIS_MODULE, @@ -470,10 +506,20 @@ if (!proc) goto cleanup_init; proc->owner = THIS_MODULE; + ret = nf_register_hook(&ip_conntrack_defrag_ops); + if (ret < 0) { + printk("ip_conntrack: can't register pre-routing defrag hook.\n"); + goto cleanup_proc; + } + ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops); + if (ret < 0) { + printk("ip_conntrack: can't register local_out defrag hook.\n"); + goto cleanup_defragops; + } ret = nf_register_hook(&ip_conntrack_in_ops); if (ret < 0) { printk("ip_conntrack: can't register pre-routing hook.\n"); - goto cleanup_proc; + goto cleanup_defraglocalops; } ret = nf_register_hook(&ip_conntrack_local_out_ops); if (ret < 0) { @@ -511,6 +557,10 @@ nf_unregister_hook(&ip_conntrack_local_out_ops); cleanup_inops: nf_unregister_hook(&ip_conntrack_in_ops); + cleanup_defraglocalops: + nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); + cleanup_defragops: + nf_unregister_hook(&ip_conntrack_defrag_ops); cleanup_proc: proc_net_remove("ip_conntrack"); cleanup_init: @@ -591,6 +641,7 @@ EXPORT_SYMBOL(ip_ct_find_proto); EXPORT_SYMBOL(__ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_helper); +EXPORT_SYMBOL(ip_conntrack_expect_alloc); EXPORT_SYMBOL(ip_conntrack_expect_related); EXPORT_SYMBOL(ip_conntrack_change_expect); EXPORT_SYMBOL(ip_conntrack_unexpect_related); @@ -602,5 +653,6 @@ EXPORT_SYMBOL(ip_conntrack_expect_list); EXPORT_SYMBOL(ip_conntrack_lock); EXPORT_SYMBOL(ip_conntrack_hash); +EXPORT_SYMBOL(ip_conntrack_untracked); EXPORT_SYMBOL_GPL(ip_conntrack_find_get); EXPORT_SYMBOL_GPL(ip_conntrack_put); diff -Nru a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c --- a/net/ipv4/netfilter/ip_conntrack_tftp.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c Sun Apr 18 13:42:40 2004 @@ -33,8 +33,8 @@ #endif #if 0 -#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ": " \ - format, ## args) +#define DEBUGP(format, args...) printk("%s:%s:" format, \ + __FILE__, __FUNCTION__ , ## args) #else #define DEBUGP(format, args...) #endif @@ -44,7 +44,7 @@ enum ip_conntrack_info ctinfo) { struct tftphdr tftph; - struct ip_conntrack_expect exp; + struct ip_conntrack_expect *exp; if (skb_copy_bits(skb, skb->nh.iph->ihl * 4 + sizeof(struct udphdr), &tftph, sizeof(tftph)) != 0) @@ -57,19 +57,29 @@ DEBUGP(""); DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); - memset(&exp, 0, sizeof(exp)); - exp.tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - exp.mask.src.ip = 0xffffffff; - exp.mask.dst.ip = 0xffffffff; - exp.mask.dst.u.udp.port = 0xffff; - exp.mask.dst.protonum = 0xffff; - exp.expectfn = NULL; + exp = ip_conntrack_expect_alloc(); + if (exp == NULL) + return NF_ACCEPT; + + exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + exp->mask.src.ip = 0xffffffff; + exp->mask.dst.ip = 0xffffffff; + exp->mask.dst.u.udp.port = 0xffff; + exp->mask.dst.protonum = 0xffff; + exp->expectfn = NULL; DEBUGP("expect: "); - DUMP_TUPLE(&exp.tuple); - DUMP_TUPLE(&exp.mask); - ip_conntrack_expect_related(ct, &exp); + DUMP_TUPLE(&exp->tuple); + DUMP_TUPLE(&exp->mask); + ip_conntrack_expect_related(exp, ct); + break; + case TFTP_OPCODE_DATA: + case TFTP_OPCODE_ACK: + DEBUGP("Data/ACK opcode\n"); + break; + case TFTP_OPCODE_ERROR: + DEBUGP("Error opcode\n"); break; default: DEBUGP("Unknown opcode\n"); diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c --- a/net/ipv4/netfilter/ip_nat_core.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/ip_nat_core.c Sun Apr 18 13:42:40 2004 @@ -1016,6 +1016,10 @@ /* FIXME: Man, this is a hack. */ IP_NF_ASSERT(ip_conntrack_destroyed == NULL); ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; + + /* Initialize fake conntrack so that NAT will skip it */ + ip_conntrack_untracked.nat.info.initialized |= + (1 << IP_NAT_MANIP_SRC) | (1 << IP_NAT_MANIP_DST); return 0; } diff -Nru a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c --- a/net/ipv4/netfilter/ip_nat_tftp.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/ip_nat_tftp.c Sun Apr 18 13:42:40 2004 @@ -47,8 +47,8 @@ #endif #if 0 -#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ": " \ - format, ## args) +#define DEBUGP(format, args...) printk("%s:%s:" format, \ + __FILE__, __FUNCTION__ , ## args) #else #define DEBUGP(format, args...) #endif diff -Nru a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c --- a/net/ipv4/netfilter/ipt_LOG.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ipt_LOG.c Sun Apr 18 13:42:41 2004 @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -26,6 +27,10 @@ MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("iptables syslog logging module"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + #if 0 #define DEBUGP printk #else @@ -324,28 +329,25 @@ /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -static unsigned int -ipt_log_target(struct sk_buff **pskb, +static void +ipt_log_packet(unsigned int hooknum, + const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, - unsigned int hooknum, - const void *targinfo, - void *userinfo) + const struct ipt_log_info *loginfo, + const char *level_string, + const char *prefix) { - const struct ipt_log_info *loginfo = targinfo; - char level_string[4] = "< >"; - - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); #ifdef CONFIG_BRIDGE_NETFILTER - if ((*pskb)->nf_bridge) { - struct net_device *physindev = (*pskb)->nf_bridge->physindev; - struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev; + if (skb->nf_bridge) { + struct net_device *physindev = skb->nf_bridge->physindev; + struct net_device *physoutdev = skb->nf_bridge->physoutdev; if (physindev && in != physindev) printk("PHYSIN=%s ", physindev->name); @@ -357,25 +359,56 @@ if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if ((*pskb)->dev && (*pskb)->dev->hard_header_len - && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) { + if (skb->dev && skb->dev->hard_header_len + && skb->mac.raw != (void*)skb->nh.iph) { int i; - unsigned char *p = (*pskb)->mac.raw; - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++) + unsigned char *p = skb->mac.raw; + for (i = 0; i < skb->dev->hard_header_len; i++,p++) printk("%02x%c", *p, - i==(*pskb)->dev->hard_header_len - 1 + i==skb->dev->hard_header_len - 1 ? ' ':':'); } else printk(" "); } - dump_packet(loginfo, *pskb, 0); + dump_packet(loginfo, skb, 0); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ipt_log_target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ipt_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); return IPT_CONTINUE; } +static void +ipt_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_log_info loginfo = { + .level = 0, + .logflags = IPT_LOG_MASK, + .prefix = "" + }; + + ipt_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); +} + static int ipt_log_checkentry(const char *tablename, const struct ipt_entry *e, void *targinfo, @@ -413,11 +446,18 @@ static int __init init(void) { - return ipt_register_target(&ipt_log_reg); + if (ipt_register_target(&ipt_log_reg)) + return -EINVAL; + if (nflog) + nf_log_register(PF_INET, &ipt_logfn); + + return 0; } static void __exit fini(void) { + if (nflog) + nf_log_unregister(PF_INET, &ipt_logfn); ipt_unregister_target(&ipt_log_reg); } diff -Nru a/net/ipv4/netfilter/ipt_NOTRACK.c b/net/ipv4/netfilter/ipt_NOTRACK.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_NOTRACK.c Sun Apr 18 13:42:41 2004 @@ -0,0 +1,75 @@ +/* This is a module which is used for setting up fake conntracks + * on packets so that they are not seen by the conntrack/NAT code. + */ +#include +#include + +#include +#include + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + /* Previously seen (loopback)? Ignore. */ + if ((*pskb)->nfct != NULL) + return IPT_CONTINUE; + + /* Attach fake conntrack entry. + If there is a real ct entry correspondig to this packet, + it'll hang aroun till timing out. We don't deal with it + for performance reasons. JK */ + (*pskb)->nfct = &ip_conntrack_untracked.infos[IP_CT_NEW]; + nf_conntrack_get((*pskb)->nfct); + + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != 0) { + printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n", + targinfosize); + return 0; + } + + if (strcmp(tablename, "raw") != 0) { + printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_notrack_reg = { + .name = "NOTRACK", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_notrack_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_notrack_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c --- a/net/ipv4/netfilter/ipt_ULOG.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/netfilter/ipt_ULOG.c Sun Apr 18 13:42:40 2004 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -64,13 +65,13 @@ #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ #if 0 -#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \ - format, ## args) +#define DEBUGP(format, args...) printk("%s:%s:" format, \ + __FILE__, __FUNCTION__ , ## args) #else #define DEBUGP(format, args...) #endif -#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0) +#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) static unsigned int nlbufsiz = 4096; MODULE_PARM(nlbufsiz, "i"); @@ -80,6 +81,10 @@ MODULE_PARM(flushtimeout, "i"); MODULE_PARM_DESC(flushtimeout, "buffer flush timeout"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + /* global data structures */ typedef struct { @@ -157,17 +162,17 @@ return skb; } -static unsigned int ipt_ulog_target(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const void *targinfo, void *userinfo) +static void ipt_ulog_packet(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct ipt_ulog_info *loginfo, + const char *prefix) { ulog_buff_t *ub; ulog_packet_msg_t *pm; size_t size, copy_len; struct nlmsghdr *nlh; - struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; /* ffs == find first bit set, necessary because userspace * is already shifting groupnumber, but we need unshifted. @@ -176,8 +181,8 @@ /* calculate the size of the skb needed */ if ((loginfo->copy_range == 0) || - (loginfo->copy_range > (*pskb)->len)) { - copy_len = (*pskb)->len; + (loginfo->copy_range > skb->len)) { + copy_len = skb->len; } else { copy_len = loginfo->copy_range; } @@ -214,19 +219,21 @@ /* copy hook, prefix, timestamp, payload, etc. */ pm->data_len = copy_len; - pm->timestamp_sec = (*pskb)->stamp.tv_sec; - pm->timestamp_usec = (*pskb)->stamp.tv_usec; - pm->mark = (*pskb)->nfmark; + pm->timestamp_sec = skb->stamp.tv_sec; + pm->timestamp_usec = skb->stamp.tv_usec; + pm->mark = skb->nfmark; pm->hook = hooknum; - if (loginfo->prefix[0] != '\0') + if (prefix != NULL) + strncpy(pm->prefix, prefix, sizeof(pm->prefix)); + else if (loginfo->prefix[0] != '\0') strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); else *(pm->prefix) = '\0'; if (in && in->hard_header_len > 0 - && (*pskb)->mac.raw != (void *) (*pskb)->nh.iph + && skb->mac.raw != (void *) skb->nh.iph && in->hard_header_len <= ULOG_MAC_LEN) { - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len); + memcpy(pm->mac, skb->mac.raw, in->hard_header_len); pm->mac_len = in->hard_header_len; } else pm->mac_len = 0; @@ -241,8 +248,8 @@ else pm->outdev_name[0] = '\0'; - /* copy_len <= (*pskb)->len, so can't fail. */ - if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0) + /* copy_len <= skb->len, so can't fail. */ + if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0) BUG(); /* check if we are building multi-part messages */ @@ -266,8 +273,7 @@ UNLOCK_BH(&ulog_lock); - return IPT_CONTINUE; - + return; nlmsg_failure: PRINTR("ipt_ULOG: error during NLMSG_PUT\n"); @@ -276,8 +282,35 @@ PRINTR("ipt_ULOG: Error building netlink message\n"); UNLOCK_BH(&ulog_lock); +} + +static unsigned int ipt_ulog_target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, void *userinfo) +{ + struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; - return IPT_CONTINUE; + ipt_ulog_packet(hooknum, *pskb, in, out, loginfo, NULL); + + return IPT_CONTINUE; +} + +static void ipt_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ipt_ulog_info loginfo = { + .nl_group = ULOG_DEFAULT_NLGROUP, + .copy_range = 0, + .qthreshold = ULOG_DEFAULT_QTHRESHOLD, + .prefix = "" + }; + + ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); } static int ipt_ulog_checkentry(const char *tablename, @@ -341,7 +374,9 @@ sock_release(nflognl->sk_socket); return -EINVAL; } - + if (nflog) + nf_log_register(PF_INET, &ipt_logfn); + return 0; } @@ -352,6 +387,8 @@ DEBUGP("ipt_ULOG: cleanup_module\n"); + if (nflog) + nf_log_unregister(PF_INET, &ipt_logfn); ipt_unregister_target(&ipt_ulog_reg); sock_release(nflognl->sk_socket); diff -Nru a/net/ipv4/netfilter/ipt_conntrack.c b/net/ipv4/netfilter/ipt_conntrack.c --- a/net/ipv4/netfilter/ipt_conntrack.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ipt_conntrack.c Sun Apr 18 13:42:41 2004 @@ -35,11 +35,13 @@ #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) - if (ct) - statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); - else - statebit = IPT_CONNTRACK_STATE_INVALID; - + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) + statebit = IPT_CONNTRACK_STATE_UNTRACKED; + else if (ct) + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); + else + statebit = IPT_CONNTRACK_STATE_INVALID; + if(sinfo->flags & IPT_CONNTRACK_STATE) { if (ct) { if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != diff -Nru a/net/ipv4/netfilter/ipt_state.c b/net/ipv4/netfilter/ipt_state.c --- a/net/ipv4/netfilter/ipt_state.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv4/netfilter/ipt_state.c Sun Apr 18 13:42:41 2004 @@ -30,7 +30,9 @@ enum ip_conntrack_info ctinfo; unsigned int statebit; - if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) + if (skb->nfct == &ip_conntrack_untracked.infos[IP_CT_NEW]) + statebit = IPT_STATE_UNTRACKED; + else if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) statebit = IPT_STATE_INVALID; else statebit = IPT_STATE_BIT(ctinfo); diff -Nru a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/iptable_raw.c Sun Apr 18 13:42:41 2004 @@ -0,0 +1,149 @@ +/* + * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT . + * + * Copyright (C) 2003 Jozsef Kadlecsik + */ +#include +#include + +#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT)) + +/* Standard entry. */ +struct ipt_standard +{ + struct ipt_entry entry; + struct ipt_standard_target target; +}; + +struct ipt_error_target +{ + struct ipt_entry_target target; + char errorname[IPT_FUNCTION_MAXNAMELEN]; +}; + +struct ipt_error +{ + struct ipt_entry entry; + struct ipt_error_target target; +}; + +static struct +{ + struct ipt_replace repl; + struct ipt_standard entries[2]; + struct ipt_error term; +} initial_table __initdata += { { "raw", RAW_VALID_HOOKS, 3, + sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error), + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + { [NF_IP_PRE_ROUTING] 0, + [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_standard), + 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + /* LOCAL_OUT */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_standard), + 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } } + }, + /* ERROR */ + { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ipt_entry), + sizeof(struct ipt_error), + 0, { 0, 0 }, { } }, + { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ipt_table packet_raw = { + .name = "raw", + .table = &initial_table.repl, + .valid_hooks = RAW_VALID_HOOKS, + .lock = RW_LOCK_UNLOCKED, + .me = THIS_MODULE +}; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ipt_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ipt_do_table(pskb, hook, in, out, &packet_raw, NULL); +} + +/* 'raw' is the very first table. */ +static struct nf_hook_ops ipt_ops[] = { + { + .hook = ipt_hook, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_RAW + }, + { + .hook = ipt_hook, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_RAW + }, +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ipt_register_table(&packet_raw); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ipt_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ipt_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ipt_ops[0]); + cleanup_table: + ipt_unregister_table(&packet_raw); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ipt_ops[i]); + + ipt_unregister_table(&packet_raw); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c --- a/net/ipv4/udp.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv4/udp.c Sun Apr 18 13:42:40 2004 @@ -975,6 +975,7 @@ /* Must be an IKE packet.. pass it through */ return 1; + decaps: /* At this point we are sure that this is an ESPinUDP packet, * so we need to remove 'len' bytes from the packet (the UDP * header and optional ESP marker bytes) and then modify the @@ -1001,6 +1002,20 @@ /* and let the caller know to send this into the ESP processor... */ return -1; + + case UDP_ENCAP_ESPINUDP_NON_IKE: + /* Check if this is a keepalive packet. If so, eat it. */ + if (len == 1 && udpdata[0] == 0xff) { + return 0; + } else if (len > 2 * sizeof(u32) + sizeof(struct ip_esp_hdr) && + udpdata32[0] == 0 && udpdata32[1] == 0) { + + /* ESP Packet with Non-IKE marker */ + len = sizeof(struct udphdr) + 2 * sizeof(u32); + goto decaps; + } else + /* Must be an IKE packet.. pass it through */ + return 1; default: if (net_ratelimit()) diff -Nru a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c --- a/net/ipv6/addrconf.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/addrconf.c Sun Apr 18 13:42:41 2004 @@ -2553,7 +2553,89 @@ return -1; } -static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) +static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca, + u32 pid, u32 seq, int event) +{ + struct ifaddrmsg *ifm; + struct nlmsghdr *nlh; + struct ifa_cacheinfo ci; + unsigned char *b = skb->tail; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); + if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; + ifm = NLMSG_DATA(nlh); + ifm->ifa_family = AF_INET6; + ifm->ifa_prefixlen = 128; + ifm->ifa_flags = IFA_F_PERMANENT; + ifm->ifa_scope = RT_SCOPE_UNIVERSE; + if (ipv6_addr_scope(&ifmca->mca_addr)&IFA_SITE) + ifm->ifa_scope = RT_SCOPE_SITE; + ifm->ifa_index = ifmca->idev->dev->ifindex; + RTA_PUT(skb, IFA_MULTICAST, 16, &ifmca->mca_addr); + ci.cstamp = (__u32)(TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) / HZ + * 100 + TIME_DELTA(ifmca->mca_cstamp, INITIAL_JIFFIES) % HZ + * 100 / HZ); + ci.tstamp = (__u32)(TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) / HZ + * 100 + TIME_DELTA(ifmca->mca_tstamp, INITIAL_JIFFIES) % HZ + * 100 / HZ); + ci.ifa_prefered = INFINITY_LIFE_TIME; + ci.ifa_valid = INFINITY_LIFE_TIME; + RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci); + nlh->nlmsg_len = skb->tail - b; + return skb->len; + +nlmsg_failure: +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, + u32 pid, u32 seq, int event) +{ + struct ifaddrmsg *ifm; + struct nlmsghdr *nlh; + struct ifa_cacheinfo ci; + unsigned char *b = skb->tail; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm)); + if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; + ifm = NLMSG_DATA(nlh); + ifm->ifa_family = AF_INET6; + ifm->ifa_prefixlen = 128; + ifm->ifa_flags = IFA_F_PERMANENT; + ifm->ifa_scope = RT_SCOPE_UNIVERSE; + if (ipv6_addr_scope(&ifaca->aca_addr)&IFA_SITE) + ifm->ifa_scope = RT_SCOPE_SITE; + ifm->ifa_index = ifaca->aca_idev->dev->ifindex; + RTA_PUT(skb, IFA_ANYCAST, 16, &ifaca->aca_addr); + ci.cstamp = (__u32)(TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) / HZ + * 100 + TIME_DELTA(ifaca->aca_cstamp, INITIAL_JIFFIES) % HZ + * 100 / HZ); + ci.tstamp = (__u32)(TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) / HZ + * 100 + TIME_DELTA(ifaca->aca_tstamp, INITIAL_JIFFIES) % HZ + * 100 / HZ); + ci.ifa_prefered = INFINITY_LIFE_TIME; + ci.ifa_valid = INFINITY_LIFE_TIME; + RTA_PUT(skb, IFA_CACHEINFO, sizeof(ci), &ci); + nlh->nlmsg_len = skb->tail - b; + return skb->len; + +nlmsg_failure: +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +enum addr_type_t +{ + UNICAST_ADDR, + MULTICAST_ADDR, + ANYCAST_ADDR, +}; + +static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, + enum addr_type_t type) { int idx, ip_idx; int s_idx, s_ip_idx; @@ -2561,7 +2643,9 @@ struct net_device *dev; struct inet6_dev *idev = NULL; struct inet6_ifaddr *ifa; - + struct ifmcaddr6 *ifmca; + struct ifacaddr6 *ifaca; + s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; read_lock(&dev_base_lock); @@ -2575,28 +2659,58 @@ if ((idev = in6_dev_get(dev)) == NULL) continue; read_lock_bh(&idev->lock); - /* unicast address */ - for (ifa = idev->addr_list; ifa; - ifa = ifa->if_next, ip_idx++) { - if (ip_idx < s_ip_idx) - continue; - if ((err = inet6_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) - goto done; - } - /* temp addr */ + switch (type) { + case UNICAST_ADDR: + /* unicast address */ + for (ifa = idev->addr_list; ifa; + ifa = ifa->if_next, ip_idx++) { + if (ip_idx < s_ip_idx) + continue; + if ((err = inet6_fill_ifaddr(skb, ifa, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) + goto done; + } + /* temp addr */ #ifdef CONFIG_IPV6_PRIVACY - for (ifa = idev->tempaddr_list; ifa; - ifa = ifa->tmp_next, ip_idx++) { - if (ip_idx < s_ip_idx) - continue; - if ((err = inet6_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) - goto done; - } + for (ifa = idev->tempaddr_list; ifa; + ifa = ifa->tmp_next, ip_idx++) { + if (ip_idx < s_ip_idx) + continue; + if ((err = inet6_fill_ifaddr(skb, ifa, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) + goto done; + } #endif + break; + case MULTICAST_ADDR: + /* multicast address */ + for (ifmca = idev->mc_list; ifmca; + ifmca = ifmca->next, ip_idx++) { + if (ip_idx < s_ip_idx) + continue; + if ((err = inet6_fill_ifmcaddr(skb, ifmca, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0) + goto done; + } + break; + case ANYCAST_ADDR: + /* anycast address */ + for (ifaca = idev->ac_list; ifaca; + ifaca = ifaca->aca_next, ip_idx++) { + if (ip_idx < s_ip_idx) + continue; + if ((err = inet6_fill_ifacaddr(skb, ifaca, + NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) + goto done; + } + break; + default: + break; + } read_unlock_bh(&idev->lock); in6_dev_put(idev); } @@ -2611,6 +2725,25 @@ return skb->len; } +static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) +{ + enum addr_type_t type = UNICAST_ADDR; + return inet6_dump_addr(skb, cb, type); +} + +static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb) +{ + enum addr_type_t type = MULTICAST_ADDR; + return inet6_dump_addr(skb, cb, type); +} + + +static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) +{ + enum addr_type_t type = ANYCAST_ADDR; + return inet6_dump_addr(skb, cb, type); +} + static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) { struct sk_buff *skb; @@ -2835,6 +2968,8 @@ [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, }, + [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, }, + [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, }, [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, }, [RTM_DELROUTE - RTM_BASE] = { .doit = inet6_rtm_delroute, }, [RTM_GETROUTE - RTM_BASE] = { .doit = inet6_rtm_getroute, diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c --- a/net/ipv6/af_inet6.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/af_inet6.c Sun Apr 18 13:42:41 2004 @@ -474,13 +474,7 @@ switch(cmd) { case SIOCGSTAMP: - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - err = copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)); - if (err) - return -EFAULT; - return 0; + return sock_get_timestamp(sk, (struct timeval *)arg); case SIOCADDRT: case SIOCDELRT: diff -Nru a/net/ipv6/ah6.c b/net/ipv6/ah6.c --- a/net/ipv6/ah6.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/ah6.c Sun Apr 18 13:42:41 2004 @@ -92,8 +92,8 @@ *nh_offset = offset; offset += ipv6_optlen(exthdr); if (!zero_out_mutable_opts(exthdr)) { - if (net_ratelimit()) - printk(KERN_WARNING "overrun hopopts\n"); + LIMIT_NETDEBUG( + printk(KERN_WARNING "overrun hopopts\n")); return 0; } nexthdr = exthdr->nexthdr; @@ -112,8 +112,8 @@ *nh_offset = offset; offset += ipv6_optlen(exthdr); if (!zero_out_mutable_opts(exthdr)) { - if (net_ratelimit()) - printk(KERN_WARNING "overrun destopt\n"); + LIMIT_NETDEBUG( + printk(KERN_WARNING "overrun destopt\n")); return 0; } nexthdr = exthdr->nexthdr; @@ -130,8 +130,8 @@ exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); nextnexthdr = exthdr->nexthdr; if (!zero_out_mutable_opts(exthdr)) { - if (net_ratelimit()) - printk(KERN_WARNING "overrun destopt\n"); + LIMIT_NETDEBUG( + printk(KERN_WARNING "overrun destopt\n")); return 0; } } @@ -162,7 +162,7 @@ } spin_lock_bh(&x->lock); - err = xfrm_check_output(x, skb, AF_INET); + err = xfrm_check_output(x, skb, AF_INET6); if (err) goto error; @@ -322,8 +322,8 @@ skb_push(skb, skb->data - skb->nh.raw); ahp->icv(ahp, skb, ah->auth_data); if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) { - if (net_ratelimit()) - printk(KERN_WARNING "ipsec ah authentication error\n"); + LIMIT_NETDEBUG( + printk(KERN_WARNING "ipsec ah authentication error\n")); x->stats.integrity_failed++; goto free_out; } @@ -368,9 +368,9 @@ if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/" + NETDEBUG(printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/" "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - ntohl(ah->spi), NIP6(iph->daddr)); + ntohl(ah->spi), NIP6(iph->daddr))); xfrm_state_put(x); } diff -Nru a/net/ipv6/datagram.c b/net/ipv6/datagram.c --- a/net/ipv6/datagram.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/datagram.c Sun Apr 18 13:42:40 2004 @@ -427,8 +427,8 @@ break; default: - if (net_ratelimit()) - printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type)); err = -EINVAL; break; }; diff -Nru a/net/ipv6/esp6.c b/net/ipv6/esp6.c --- a/net/ipv6/esp6.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/esp6.c Sun Apr 18 13:42:41 2004 @@ -278,9 +278,8 @@ padlen = nexthdr[0]; if (padlen+2 >= elen) { - if (net_ratelimit()) { - printk(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen); - } + LIMIT_NETDEBUG( + printk(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen)); ret = -EINVAL; goto out; } diff -Nru a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c --- a/net/ipv6/exthdrs.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/exthdrs.c Sun Apr 18 13:42:40 2004 @@ -159,6 +159,7 @@ 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))) { + IP6_INC_STATS_BH(Ip6InHdrErrors); kfree_skb(skb); return -1; } @@ -171,6 +172,7 @@ return 1; } + IP6_INC_STATS_BH(Ip6InHdrErrors); return -1; } @@ -234,6 +236,7 @@ if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || skb->pkt_type != PACKET_HOST) { + IP6_INC_STATS_BH(Ip6InAddrErrors); kfree_skb(skb); return -1; } @@ -249,11 +252,13 @@ } if (hdr->type != IPV6_SRCRT_TYPE_0) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); return -1; } if (hdr->hdrlen & 0x01) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); return -1; } @@ -266,6 +271,7 @@ n = hdr->hdrlen >> 1; if (hdr->segments_left > n) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); return -1; } @@ -276,8 +282,11 @@ if (skb_cloned(skb)) { struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); kfree_skb(skb); - if (skb2 == NULL) + /* the copy is a forwarded packet */ + if (skb2 == NULL) { + IP6_INC_STATS_BH(Ip6OutDiscards); return -1; + } *skbp = skb = skb2; opt = (struct inet6_skb_parm *)skb2->cb; hdr = (struct ipv6_rt_hdr *) skb2->h.raw; @@ -293,6 +302,7 @@ addr += i - 1; if (ipv6_addr_is_multicast(addr)) { + IP6_INC_STATS_BH(Ip6InAddrErrors); kfree_skb(skb); return -1; } @@ -309,6 +319,7 @@ } if (skb->dst->dev->flags&IFF_LOOPBACK) { if (skb->nh.ipv6h->hop_limit <= 1) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); kfree_skb(skb); @@ -410,8 +421,8 @@ ((struct inet6_skb_parm*)skb->cb)->ra = optoff; return 1; } - if (net_ratelimit()) - printk(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", skb->nh.raw[optoff+1]); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", skb->nh.raw[optoff+1])); kfree_skb(skb); return 0; } @@ -423,17 +434,20 @@ u32 pkt_len; if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { - if (net_ratelimit()) - printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1])); + IP6_INC_STATS_BH(Ip6InHdrErrors); goto drop; } pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); if (pkt_len <= IPV6_MAXPLEN) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); return 0; } if (skb->nh.ipv6h->payload_len) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); return 0; } diff -Nru a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/icmp.c Sun Apr 18 13:42:40 2004 @@ -329,8 +329,8 @@ * for now we don't know that. */ if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) { - if (net_ratelimit()) - printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n"); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n")); return; } @@ -338,8 +338,8 @@ * Never answer to a ICMP packet. */ if (is_ineligible(skb)) { - if (net_ratelimit()) - printk(KERN_DEBUG "icmpv6_send: no reply to icmp error\n"); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "icmpv6_send: no reply to icmp error\n")); return; } @@ -385,8 +385,8 @@ len = skb->len - msg.offset; len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); if (len < 0) { - if (net_ratelimit()) - printk(KERN_DEBUG "icmp: len problem\n"); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "icmp: len problem\n")); goto out_dst_release; } @@ -570,17 +570,17 @@ skb->ip_summed = CHECKSUM_UNNECESSARY; if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, skb->csum)) { - if (net_ratelimit()) - printk(KERN_DEBUG "ICMPv6 hw checksum failed\n"); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "ICMPv6 hw checksum failed\n")); skb->ip_summed = CHECKSUM_NONE; } } if (skb->ip_summed == CHECKSUM_NONE) { if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, skb_checksum(skb, 0, skb->len, 0))) { - if (net_ratelimit()) + LIMIT_NETDEBUG( printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n", - NIP6(*saddr), NIP6(*daddr)); + NIP6(*saddr), NIP6(*daddr))); goto discard_it; } } @@ -646,11 +646,12 @@ break; case ICMPV6_MGM_REDUCTION: + case ICMPV6_MLD2_REPORT: break; default: - if (net_ratelimit()) - printk(KERN_DEBUG "icmpv6: msg of unknown type\n"); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "icmpv6: msg of unknown type\n")); /* informational */ if (type & ICMPV6_INFOMSG_MASK) diff -Nru a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c --- a/net/ipv6/ip6_input.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/ip6_input.c Sun Apr 18 13:42:41 2004 @@ -79,8 +79,10 @@ if (skb->len < sizeof(struct ipv6hdr)) goto err; - if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) { + IP6_INC_STATS_BH(Ip6InHdrErrors); goto drop; + } hdr = skb->nh.ipv6h; @@ -94,8 +96,10 @@ if (pkt_len + sizeof(struct ipv6hdr) > skb->len) goto truncated; if (pkt_len + sizeof(struct ipv6hdr) < skb->len) { - if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))) + if (__pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr))){ + IP6_INC_STATS_BH(Ip6InHdrErrors); goto drop; + } hdr = skb->nh.ipv6h; if (skb->ip_summed == CHECKSUM_HW) skb->ip_summed = CHECKSUM_NONE; @@ -206,6 +210,7 @@ return 0; discard: + IP6_INC_STATS_BH(Ip6InDiscards); rcu_read_unlock(); kfree_skb(skb); return 0; diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/ip6_output.c Sun Apr 18 13:42:40 2004 @@ -87,6 +87,7 @@ } else if (dst->neighbour) return dst->neighbour->output(skb); + IP6_INC_STATS_BH(Ip6OutNoRoutes); kfree_skb(skb); return -EINVAL; @@ -131,6 +132,7 @@ ip6_dev_loopback_xmit); if (skb->nh.ipv6h->hop_limit == 0) { + IP6_INC_STATS(Ip6OutDiscards); kfree_skb(skb); return 0; } @@ -167,8 +169,9 @@ dst = ip6_route_output(skb->sk, &fl); if (dst->error) { - if (net_ratelimit()) - printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); + IP6_INC_STATS(Ip6OutNoRoutes); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n")); dst_release(dst); return -EINVAL; } @@ -224,8 +227,10 @@ struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); kfree_skb(skb); skb = skb2; - if (skb == NULL) + if (skb == NULL) { + IP6_INC_STATS(Ip6OutDiscards); return -ENOBUFS; + } if (sk) skb_set_owner_w(skb, sk); } @@ -265,6 +270,7 @@ printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + IP6_INC_STATS(Ip6FragFails); kfree_skb(skb); return -EMSGSIZE; } @@ -345,8 +351,10 @@ if (ipv6_devconf.forwarding == 0) goto error; - if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) + if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { + IP6_INC_STATS(Ip6InDiscards); goto drop; + } skb->ip_summed = CHECKSUM_NONE; @@ -382,8 +390,10 @@ return -ETIMEDOUT; } - if (!xfrm6_route_forward(skb)) + if (!xfrm6_route_forward(skb)) { + IP6_INC_STATS(Ip6InDiscards); goto drop; + } /* IPv6 specs say nothing about it, but it is clear that we cannot send redirects to source routed frames. @@ -420,12 +430,15 @@ skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_pmtu(dst), skb->dev); IP6_INC_STATS_BH(Ip6InTooBigErrors); + IP6_INC_STATS_BH(Ip6FragFails); kfree_skb(skb); return -EMSGSIZE; } - if (skb_cow(skb, dst->dev->hard_header_len)) + if (skb_cow(skb, dst->dev->hard_header_len)) { + IP6_INC_STATS(Ip6OutDiscards); goto drop; + } hdr = skb->nh.ipv6h; @@ -648,6 +661,7 @@ if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { NETDEBUG(printk(KERN_INFO "IPv6: frag: no memory for new fragment!\n")); + IP6_INC_STATS(Ip6FragFails); err = -ENOMEM; goto fail; } @@ -1062,6 +1076,7 @@ ipv6_addr_copy(&hdr->daddr, final_dst); skb->dst = dst_clone(&rt->u.dst); + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); if (err) { if (err > 0) @@ -1092,8 +1107,10 @@ struct ipv6_pinfo *np = inet6_sk(sk); struct sk_buff *skb; - while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) + while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { + IP6_INC_STATS(Ip6OutDiscards); kfree_skb(skb); + } inet->cork.flags &= ~IPCORK_OPT; diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/mcast.c Sun Apr 18 13:42:41 2004 @@ -1317,6 +1317,7 @@ struct inet6_dev *idev = in6_dev_get(skb->dev); int err; + IP6_INC_STATS(Ip6OutRequests); payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - sizeof(struct ipv6hdr); mldlen = skb->tail - skb->h.raw; @@ -1326,8 +1327,12 @@ IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, dev_queue_xmit); - if (!err) + if (!err) { ICMP6_INC_STATS(idev,Icmp6OutMsgs); + IP6_INC_STATS(Ip6OutMcastPkts); + } else + IP6_INC_STATS(Ip6OutDiscards); + if (likely(idev != NULL)) in6_dev_put(idev); } @@ -1608,6 +1613,7 @@ IPV6_TLV_ROUTERALERT, 2, 0, 0, IPV6_TLV_PADN, 0 }; + IP6_INC_STATS(Ip6OutRequests); snd_addr = addr; if (type == ICMPV6_MGM_REDUCTION) { snd_addr = &all_routers; @@ -1620,8 +1626,10 @@ skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); - if (skb == NULL) + if (skb == NULL) { + IP6_INC_STATS(Ip6OutDiscards); return; + } skb_reserve(skb, LL_RESERVED_SPACE(dev)); if (dev->hard_header) { @@ -1664,13 +1672,16 @@ else ICMP6_INC_STATS(idev, Icmp6OutGroupMembResponses); ICMP6_INC_STATS(idev, Icmp6OutMsgs); - } + IP6_INC_STATS(Ip6OutMcastPkts); + } else + IP6_INC_STATS(Ip6OutDiscards); if (likely(idev != NULL)) in6_dev_put(idev); return; out: + IP6_INC_STATS(Ip6OutDiscards); kfree_skb(skb); } diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c --- a/net/ipv6/ndisc.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/ndisc.c Sun Apr 18 13:42:41 2004 @@ -452,6 +452,7 @@ skb->dst = dst; idev = in6_dev_get(dst->dev); + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutNeighborAdvertisements); @@ -535,6 +536,7 @@ /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutNeighborSolicits); @@ -607,6 +609,7 @@ /* send it! */ skb->dst = dst; idev = in6_dev_get(dst->dev); + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutRouterSolicits); @@ -761,7 +764,7 @@ if (ipv6_chk_acast_addr(dev, &msg->target) || (idev->cnf.forwarding && pneigh_lookup(&nd_tbl, &msg->target, dev, 0))) { - if (skb->stamp.tv_sec != 0 && + if (skb->stamp.tv_sec != LOCALLY_ENQUEUED && skb->pkt_type != PACKET_HOST && inc != 0 && idev->nd_parms->proxy_delay != 0) { @@ -1332,6 +1335,7 @@ buff->dst = dst; idev = in6_dev_get(dst->dev); + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); if (!err) { ICMP6_INC_STATS(idev, Icmp6OutRedirects); @@ -1401,6 +1405,10 @@ switch (event) { case NETDEV_CHANGEADDR: neigh_changeaddr(&nd_tbl, dev); + fib6_run_gc(0); + break; + case NETDEV_DOWN: + neigh_ifdown(&nd_tbl, dev); fib6_run_gc(0); break; default: diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig --- a/net/ipv6/netfilter/Kconfig Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/netfilter/Kconfig Sun Apr 18 13:42:41 2004 @@ -218,5 +218,17 @@ To compile it as a module, choose M here. If unsure, say N. #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES +config IP6_NF_RAW + tristate 'raw table support (required for TRACE)' + depends on IP6_NF_IPTABLES + help + This option adds a `raw' table to ip6tables. This table is the very + first in the netfilter framework and hooks in at the PREROUTING + and OUTPUT chains. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + help + endmenu diff -Nru a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile --- a/net/ipv6/netfilter/Makefile Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/netfilter/Makefile Sun Apr 18 13:42:41 2004 @@ -21,4 +21,5 @@ obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o +obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o diff -Nru a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c --- a/net/ipv6/netfilter/ip6t_LOG.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/netfilter/ip6t_LOG.c Sun Apr 18 13:42:40 2004 @@ -18,12 +18,17 @@ #include #include #include +#include #include MODULE_AUTHOR("Jan Rekorajski "); MODULE_DESCRIPTION("IP6 tables LOG target module"); MODULE_LICENSE("GPL"); +static unsigned int nflog = 1; +MODULE_PARM(nflog, "i"); +MODULE_PARM_DESC(nflog, "register as internal netfilter logging module"); + struct in_device; #include #include @@ -265,40 +270,38 @@ } } -static unsigned int -ip6t_log_target(struct sk_buff **pskb, - unsigned int hooknum, +static void +ip6t_log_packet(unsigned int hooknum, + const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, - const void *targinfo, - void *userinfo) + const struct ip6t_log_info *loginfo, + const char *level_string, + const char *prefix) { - struct ipv6hdr *ipv6h = (*pskb)->nh.ipv6h; - const struct ip6t_log_info *loginfo = targinfo; - char level_string[4] = "< >"; + struct ipv6hdr *ipv6h = skb->nh.ipv6h; - level_string[1] = '0' + (loginfo->level % 8); spin_lock_bh(&log_lock); printk(level_string); printk("%sIN=%s OUT=%s ", - loginfo->prefix, + prefix == NULL ? loginfo->prefix : prefix, in ? in->name : "", out ? out->name : ""); if (in && !out) { /* MAC logging for input chain only. */ printk("MAC="); - if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)ipv6h) { - if ((*pskb)->dev->type != ARPHRD_SIT){ + if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) { + if (skb->dev->type != ARPHRD_SIT){ int i; - unsigned char *p = (*pskb)->mac.raw; - for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++) + unsigned char *p = skb->mac.raw; + for (i = 0; i < skb->dev->hard_header_len; i++,p++) printk("%02x%c", *p, - i==(*pskb)->dev->hard_header_len - 1 + i==skb->dev->hard_header_len - 1 ? ' ':':'); } else { int i; - unsigned char *p = (*pskb)->mac.raw; - if ( p - (ETH_ALEN*2+2) > (*pskb)->head ){ + unsigned char *p = skb->mac.raw; + if ( p - (ETH_ALEN*2+2) > skb->head ){ p -= (ETH_ALEN+2); for (i = 0; i < (ETH_ALEN); i++,p++) printk("%02x%s", *p, @@ -309,10 +312,10 @@ i == ETH_ALEN-1 ? ' ' : ':'); } - if (((*pskb)->dev->addr_len == 4) && - (*pskb)->dev->hard_header_len > 20){ + if ((skb->dev->addr_len == 4) && + skb->dev->hard_header_len > 20){ printk("TUNNEL="); - p = (*pskb)->mac.raw + 12; + p = skb->mac.raw + 12; for (i = 0; i < 4; i++,p++) printk("%3d%s", *p, i == 3 ? "->" : "."); @@ -328,10 +331,41 @@ dump_packet(loginfo, ipv6h, 1); printk("\n"); spin_unlock_bh(&log_lock); +} + +static unsigned int +ip6t_log_target(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_log_info *loginfo = targinfo; + char level_string[4] = "< >"; + + level_string[1] = '0' + (loginfo->level % 8); + ip6t_log_packet(hooknum, *pskb, in, out, loginfo, level_string, NULL); return IP6T_CONTINUE; } +static void +ip6t_logfn(unsigned int hooknum, + const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const char *prefix) +{ + struct ip6t_log_info loginfo = { + .level = 0, + .logflags = IP6T_LOG_MASK, + .prefix = "" + }; + + ip6t_log_packet(hooknum, skb, in, out, &loginfo, KERN_WARNING, prefix); +} + static int ip6t_log_checkentry(const char *tablename, const struct ip6t_entry *e, void *targinfo, @@ -360,20 +394,27 @@ return 1; } -static struct ip6t_target ip6t_log_reg -= { { NULL, NULL }, "LOG", ip6t_log_target, ip6t_log_checkentry, NULL, - THIS_MODULE }; +static struct ip6t_target ip6t_log_reg = { + .name = "LOG", + .target = ip6t_log_target, + .checkentry = ip6t_log_checkentry, + .me = THIS_MODULE, +}; static int __init init(void) { if (ip6t_register_target(&ip6t_log_reg)) return -EINVAL; + if (nflog) + nf_log_register(PF_INET6, &ip6t_logfn); return 0; } static void __exit fini(void) { + if (nflog) + nf_log_unregister(PF_INET6, &ip6t_logfn); ip6t_unregister_target(&ip6t_log_reg); } diff -Nru a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv6/netfilter/ip6table_raw.c Sun Apr 18 13:42:41 2004 @@ -0,0 +1,154 @@ +/* + * IPv6 raw table, a port of the IPv4 raw table to IPv6 + * + * Copyright (C) 2003 Jozsef Kadlecsik + */ +#include +#include + +#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT)) + +#if 0 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args) +#else +#define DEBUGP(x, args...) +#endif + +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + +static struct +{ + struct ip6t_replace repl; + struct ip6t_standard entries[2]; + struct ip6t_error term; +} initial_table __initdata += { { "raw", RAW_VALID_HOOKS, 3, + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error), + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + /* LOCAL_OUT */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + }, + /* ERROR */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_error), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ip6t_table packet_raw = { + .name = "raw", + .table = &initial_table.repl, + .valid_hooks = RAW_VALID_HOOKS, + .lock = RW_LOCK_UNLOCKED, + .me = THIS_MODULE +}; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ip6t_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip6t_do_table(pskb, hook, in, out, &packet_raw, NULL); +} + +static struct nf_hook_ops ip6t_ops[] = { + { + .hook = ip6t_hook, + .pf = PF_INET6, + .hooknum = NF_IP6_PRE_ROUTING, + .priority = NF_IP6_PRI_FIRST + }, + { + .hook = ip6t_hook, + .pf = PF_INET6, + .hooknum = NF_IP6_LOCAL_OUT, + .priority = NF_IP6_PRI_FIRST + }, +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ip6t_register_table(&packet_raw); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ip6t_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ip6t_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ip6t_ops[0]); + cleanup_table: + ip6t_unregister_table(&packet_raw); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ip6t_ops[i]); + + ip6t_unregister_table(&packet_raw); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c --- a/net/ipv6/raw.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/raw.c Sun Apr 18 13:42:40 2004 @@ -328,7 +328,8 @@ if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, skb->len, inet->num, skb->csum)) { - NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "raw v6 hw csum failure.\n")); + LIMIT_NETDEBUG( + printk(KERN_DEBUG "raw v6 hw csum failure.\n")); skb->ip_summed = CHECKSUM_NONE; } } @@ -526,6 +527,7 @@ if (err) goto error_fault; + IP6_INC_STATS(Ip6OutRequests); err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); if (err > 0) diff -Nru a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c --- a/net/ipv6/reassembly.c Sun Apr 18 13:42:40 2004 +++ b/net/ipv6/reassembly.c Sun Apr 18 13:42:40 2004 @@ -426,6 +426,7 @@ ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); if ((unsigned int)end > IPV6_MAXPLEN) { + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); return; } @@ -452,6 +453,7 @@ /* RFC2460 says always send parameter problem in * this case. -DaveM */ + IP6_INC_STATS_BH(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, offsetof(struct ipv6hdr, payload_len)); return; @@ -570,6 +572,7 @@ return; err: + IP6_INC_STATS(Ip6ReasmFails); kfree_skb(skb); } @@ -694,10 +697,12 @@ /* Jumbo payload inhibits frag. header */ if (hdr->payload_len==0) { + IP6_INC_STATS(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); return -1; } if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) { + IP6_INC_STATS(Ip6InHdrErrors); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); return -1; } diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c --- a/net/ipv6/tcp_ipv6.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/tcp_ipv6.c Sun Apr 18 13:42:41 2004 @@ -1425,7 +1425,7 @@ if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,skb->csum)) return 0; - NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v6 csum failed\n")); + LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n")); } if (skb->len <= 76) { if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c --- a/net/ipv6/udp.c Sun Apr 18 13:42:41 2004 +++ b/net/ipv6/udp.c Sun Apr 18 13:42:41 2004 @@ -634,8 +634,8 @@ /* RFC 2460 section 8.1 says that we SHOULD log this error. Well, it is reasonable. */ - if (net_ratelimit()) - printk(KERN_INFO "IPv6: udp checksum is 0\n"); + LIMIT_NETDEBUG( + printk(KERN_INFO "IPv6: udp checksum is 0\n")); goto discard; } @@ -650,7 +650,7 @@ if (skb->ip_summed==CHECKSUM_HW) { skb->ip_summed = CHECKSUM_UNNECESSARY; if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { - NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.\n")); + LIMIT_NETDEBUG(printk(KERN_DEBUG "udp v6 hw csum failure.\n")); skb->ip_summed = CHECKSUM_NONE; } } @@ -913,6 +913,7 @@ if (msg->msg_controllen) { opt = &opt_space; memset(opt, 0, sizeof(struct ipv6_txoptions)); + opt->tot_len = sizeof(*opt); err = datagram_send_ctl(msg, fl, opt, &hlimit); if (err < 0) { @@ -970,7 +971,7 @@ /* ... which is an evident application bug. --ANK */ release_sock(sk); - NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp cork app bug 2\n")); + LIMIT_NETDEBUG(printk(KERN_DEBUG "udp cork app bug 2\n")); err = -EINVAL; goto out; } diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c --- a/net/ipx/af_ipx.c Sun Apr 18 13:42:40 2004 +++ b/net/ipx/af_ipx.c Sun Apr 18 13:42:40 2004 @@ -1797,7 +1797,8 @@ copied); if (rc) goto out_free; - sk->sk_stamp = skb->stamp; + if (skb->stamp.tv_sec) + sk->sk_stamp = skb->stamp; msg->msg_namelen = sizeof(*sipx); @@ -1870,15 +1871,8 @@ break; case SIOCGSTAMP: rc = -EINVAL; - if (sk) { - rc = -ENOENT; - if (!sk->sk_stamp.tv_sec) - break; - rc = -EFAULT; - if (!copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval))) - rc = 0; - } + if (sk) + rc = sock_get_timestamp(sk, (struct timeval *)arg); break; case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: diff -Nru a/net/irda/Kconfig b/net/irda/Kconfig --- a/net/irda/Kconfig Sun Apr 18 13:42:41 2004 +++ b/net/irda/Kconfig Sun Apr 18 13:42:41 2004 @@ -2,11 +2,9 @@ # IrDA protocol configuration # -menu "IrDA (infrared) support" +menuconfig IRDA depends on NET - -config IRDA - tristate "IrDA subsystem support" + tristate "IrDA (infrared) subsystem support" ---help--- Say Y here if you want to build support for the IrDA (TM) protocols. The Infrared Data Associations (tm) specifies standards for wireless @@ -94,6 +92,4 @@ If unsure, say Y (since it makes it easier to find the bugs). source "drivers/net/irda/Kconfig" - -endmenu diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c --- a/net/irda/af_irda.c Sun Apr 18 13:42:40 2004 +++ b/net/irda/af_irda.c Sun Apr 18 13:42:40 2004 @@ -1796,14 +1796,8 @@ } case SIOCGSTAMP: - if (sk != NULL) { - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - if (copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval))) - return -EFAULT; - return 0; - } + if (sk != NULL) + return sock_get_timestamp(sk, (struct timeval *)arg); return -EINVAL; case SIOCGIFADDR: diff -Nru a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c --- a/net/irda/irlan/irlan_client.c Sun Apr 18 13:42:41 2004 +++ b/net/irda/irlan/irlan_client.c Sun Apr 18 13:42:41 2004 @@ -343,6 +343,52 @@ irttp_data_request(self->client.tsap_ctrl, skb); } + +/* + * Function print_ret_code (code) + * + * Print return code of request to peer IrLAN layer. + * + */ +static void print_ret_code(__u8 code) +{ + switch(code) { + case 0: + printk(KERN_INFO "Success\n"); + break; + case 1: + WARNING("IrLAN: Insufficient resources\n"); + break; + case 2: + WARNING("IrLAN: Invalid command format\n"); + break; + case 3: + WARNING("IrLAN: Command not supported\n"); + break; + case 4: + WARNING("IrLAN: Parameter not supported\n"); + break; + case 5: + WARNING("IrLAN: Value not supported\n"); + break; + case 6: + WARNING("IrLAN: Not open\n"); + break; + case 7: + WARNING("IrLAN: Authentication required\n"); + break; + case 8: + WARNING("IrLAN: Invalid password\n"); + break; + case 9: + WARNING("IrLAN: Protocol error\n"); + break; + case 255: + WARNING("IrLAN: Asynchronous status\n"); + break; + } +} + /* * Function irlan_client_parse_response (self, skb) * diff -Nru a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c --- a/net/irda/irlan/irlan_common.c Sun Apr 18 13:42:41 2004 +++ b/net/irda/irlan/irlan_common.c Sun Apr 18 13:42:41 2004 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -75,14 +76,14 @@ static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */ #ifdef CONFIG_PROC_FS -static char *irlan_access[] = { +static const char *irlan_access[] = { "UNKNOWN", "DIRECT", "PEER", "HOSTED" }; -static char *irlan_media[] = { +static const char *irlan_media[] = { "UNKNOWN", "802.3", "802.5" @@ -115,12 +116,12 @@ * Initialize IrLAN layer * */ -int __init irlan_init(void) +static int __init irlan_init(void) { struct irlan_cb *new; __u16 hints; - IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); + IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); #ifdef CONFIG_PROC_FS { struct proc_dir_entry *proc; @@ -156,7 +157,7 @@ return 0; } -void __exit irlan_cleanup(void) +static void __exit irlan_cleanup(void) { struct irlan_cb *self, *next; @@ -191,9 +192,7 @@ IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); /* Create network device with irlan */ - dev = alloc_netdev(sizeof(*self), - eth ? "eth%d" : "irlan%d", - irlan_eth_setup); + dev = alloc_irlandev(eth ? "eth%d" : "irlan%d"); if (!dev) return NULL; @@ -209,6 +208,19 @@ /* Provider access can only be PEER, DIRECT, or HOSTED */ self->provider.access_type = access; + if (access == ACCESS_DIRECT) { + /* + * Since we are emulating an IrLAN sever we will have to + * give ourself an ethernet address! + */ + dev->dev_addr[0] = 0x40; + dev->dev_addr[1] = 0x00; + dev->dev_addr[2] = 0x00; + dev->dev_addr[3] = 0x00; + get_random_bytes(dev->dev_addr+4, 1); + get_random_bytes(dev->dev_addr+5, 1); + } + self->media = MEDIA_802_3; self->disconnect_reason = LM_USER_REQUEST; init_timer(&self->watchdog_timer); @@ -242,16 +254,14 @@ */ static void __irlan_close(struct irlan_cb *self) { - struct sk_buff *skb; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); ASSERT_RTNL(); ASSERT(self != NULL, return;); ASSERT(self->magic == IRLAN_MAGIC, return;); - del_timer(&self->watchdog_timer); - del_timer(&self->client.kick_timer); + del_timer_sync(&self->watchdog_timer); + del_timer_sync(&self->client.kick_timer); /* Close all open connections and remove TSAPs */ irlan_close_tsaps(self); @@ -260,8 +270,7 @@ iriap_close(self->client.iriap); /* Remove frames queued on the control channel */ - while ((skb = skb_dequeue(&self->client.txq))) - dev_kfree_skb(skb); + skb_queue_purge(&self->client.txq); /* Unregister and free self via destructor */ unregister_netdevice(self->dev); @@ -303,7 +312,7 @@ self->max_sdu_size = max_sdu_size; self->max_header_size = max_header_size; - IRDA_DEBUG(0, "IrLAN, We are now connected!\n"); + IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__); del_timer(&self->watchdog_timer); @@ -345,7 +354,7 @@ /* TODO: we could set the MTU depending on the max_sdu_size */ - IRDA_DEBUG(2, "IrLAN, We are now connected!\n"); + IRDA_DEBUG(0, "%s: We are now connected!\n", __FUNCTION__); del_timer(&self->watchdog_timer); /* @@ -451,7 +460,7 @@ notify.udata_indication = irlan_eth_receive; notify.connect_indication = irlan_connect_indication; notify.connect_confirm = irlan_connect_confirm; - /*notify.flow_indication = irlan_eth_flow_indication;*/ + notify.flow_indication = irlan_eth_flow_indication; notify.disconnect_indication = irlan_disconnect_indication; notify.instance = self; strlcpy(notify.name, "IrLAN data", sizeof(notify.name)); @@ -1168,51 +1177,6 @@ } #endif -/* - * Function print_ret_code (code) - * - * Print return code of request to peer IrLAN layer. - * - */ -void print_ret_code(__u8 code) -{ - switch(code) { - case 0: - printk(KERN_INFO "Success\n"); - break; - case 1: - WARNING("IrLAN: Insufficient resources\n"); - break; - case 2: - WARNING("IrLAN: Invalid command format\n"); - break; - case 3: - WARNING("IrLAN: Command not supported\n"); - break; - case 4: - WARNING("IrLAN: Parameter not supported\n"); - break; - case 5: - WARNING("IrLAN: Value not supported\n"); - break; - case 6: - WARNING("IrLAN: Not open\n"); - break; - case 7: - WARNING("IrLAN: Authentication required\n"); - break; - case 8: - WARNING("IrLAN: Invalid password\n"); - break; - case 9: - WARNING("IrLAN: Protocol error\n"); - break; - case 255: - WARNING("IrLAN: Asynchronous status\n"); - break; - } -} - MODULE_AUTHOR("Dag Brattli "); MODULE_DESCRIPTION("The Linux IrDA LAN protocol"); MODULE_LICENSE("GPL"); @@ -1222,19 +1186,6 @@ MODULE_PARM(access, "i"); MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3"); -/* - * Function init_module (void) - * - * Initialize the IrLAN module, this function is called by the - * modprobe(1) program. - */ module_init(irlan_init); - -/* - * Function cleanup_module (void) - * - * Remove the IrLAN module, this function is called by the rmmod(1) - * program - */ module_exit(irlan_cleanup); diff -Nru a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c --- a/net/irda/irlan/irlan_eth.c Sun Apr 18 13:42:40 2004 +++ b/net/irda/irlan/irlan_eth.c Sun Apr 18 13:42:40 2004 @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -41,20 +40,20 @@ #include #include +static int irlan_eth_open(struct net_device *dev); +static int irlan_eth_close(struct net_device *dev); +static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev); +static void irlan_eth_set_multicast_list( struct net_device *dev); +static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev); + /* - * Function irlan_eth_init (dev) + * Function irlan_eth_setup (dev) * * The network device initialization function. * */ -void irlan_eth_setup(struct net_device *dev) +static void irlan_eth_setup(struct net_device *dev) { - struct irlan_cb *self; - - IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - - self = (struct irlan_cb *) dev->priv; - dev->open = irlan_eth_open; dev->stop = irlan_eth_close; dev->hard_start_xmit = irlan_eth_xmit; @@ -71,20 +70,30 @@ * Queueing here as well can introduce some strange latency * problems, which we will avoid by setting the queue size to 0. */ - dev->tx_queue_len = 0; + /* + * The bugs in IrTTP and IrLAN that created this latency issue + * have now been fixed, and we can propagate flow control properly + * to the network layer. However, this requires a minimal queue of + * packets for the device. + * Without flow control, the Tx Queue is 14 (ttp) + 0 (dev) = 14 + * With flow control, the Tx Queue is 7 (ttp) + 4 (dev) = 11 + * See irlan_eth_flow_indication()... + * Note : this number was randomly selected and would need to + * be adjusted. + * Jean II */ + dev->tx_queue_len = 4; +} - if (self->provider.access_type == ACCESS_DIRECT) { - /* - * Since we are emulating an IrLAN sever we will have to - * give ourself an ethernet address! - */ - dev->dev_addr[0] = 0x40; - dev->dev_addr[1] = 0x00; - dev->dev_addr[2] = 0x00; - dev->dev_addr[3] = 0x00; - get_random_bytes(dev->dev_addr+4, 1); - get_random_bytes(dev->dev_addr+5, 1); - } +/* + * Function alloc_irlandev + * + * Allocate network device and control block + * + */ +struct net_device *alloc_irlandev(const char *name) +{ + return alloc_netdev(sizeof(struct irlan_cb), name, + irlan_eth_setup); } /* @@ -93,18 +102,12 @@ * Network device has been opened by user * */ -int irlan_eth_open(struct net_device *dev) +static int irlan_eth_open(struct net_device *dev) { - struct irlan_cb *self; + struct irlan_cb *self = netdev_priv(dev); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - ASSERT(dev != NULL, return -1;); - - self = (struct irlan_cb *) dev->priv; - - ASSERT(self != NULL, return -1;); - /* Ready to play! */ netif_stop_queue(dev); /* Wait until data link is ready */ @@ -112,10 +115,10 @@ self->disconnect_reason = 0; irlan_client_wakeup(self, self->saddr, self->daddr); - /* Make sure we have a hardware address before we return, so DHCP clients gets happy */ - interruptible_sleep_on(&self->open_wait); - - return 0; + /* Make sure we have a hardware address before we return, + so DHCP clients gets happy */ + return wait_event_interruptible(self->open_wait, + !self->tsap_data->connected); } /* @@ -126,10 +129,9 @@ * close timer, so that the instance will be removed if we are unable * to discover the remote device after the disconnect. */ -int irlan_eth_close(struct net_device *dev) +static int irlan_eth_close(struct net_device *dev) { - struct irlan_cb *self = (struct irlan_cb *) dev->priv; - struct sk_buff *skb; + struct irlan_cb *self = netdev_priv(dev); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); @@ -143,8 +145,7 @@ irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL); /* Remove frames queued on the control channel */ - while ((skb = skb_dequeue(&self->client.txq))) - dev_kfree_skb(skb); + skb_queue_purge(&self->client.txq); self->client.tx_busy = 0; @@ -157,16 +158,11 @@ * Transmits ethernet frames over IrDA link. * */ -int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev) +static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irlan_cb *self; + struct irlan_cb *self = netdev_priv(dev); int ret; - self = (struct irlan_cb *) dev->priv; - - ASSERT(self != NULL, return 0;); - ASSERT(self->magic == IRLAN_MAGIC, return 0;); - /* skb headroom large enough to contain all IrDA-headers? */ if ((skb_headroom(skb) < self->max_header_size) || (skb_shared(skb))) { struct sk_buff *new_skb = @@ -220,9 +216,7 @@ */ int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) { - struct irlan_cb *self; - - self = (struct irlan_cb *) instance; + struct irlan_cb *self = instance; if (skb == NULL) { ++self->stats.rx_dropped; @@ -251,6 +245,14 @@ * * Do flow control between IP/Ethernet and IrLAN/IrTTP. This is done by * controlling the queue stop/start. + * + * The IrDA link layer has the advantage to have flow control, and + * IrTTP now properly handles that. Flow controlling the higher layers + * prevent us to drop Tx packets in here (up to 15% for a TCP socket, + * more for UDP socket). + * Also, this allow us to reduce the overall transmit queue, which means + * less latency in case of mixed traffic. + * Jean II */ void irlan_eth_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) { @@ -266,37 +268,25 @@ ASSERT(dev != NULL, return;); + IRDA_DEBUG(0, "%s() : flow %s ; running %d\n", __FUNCTION__, + flow == FLOW_STOP ? "FLOW_STOP" : "FLOW_START", + netif_running(dev)); + switch (flow) { case FLOW_STOP: + /* IrTTP is full, stop higher layers */ netif_stop_queue(dev); break; case FLOW_START: default: /* Tell upper layers that its time to transmit frames again */ /* Schedule network layer */ - netif_start_queue(dev); + netif_wake_queue(dev); break; } } /* - * Function irlan_eth_rebuild_header (buff, dev, dest, skb) - * - * If we don't want to use ARP. Currently not used!! - * - */ -void irlan_eth_rebuild_header(void *buff, struct net_device *dev, - unsigned long dest, struct sk_buff *skb) -{ - struct ethhdr *eth = (struct ethhdr *) buff; - - memcpy(eth->h_source, dev->dev_addr, dev->addr_len); - memcpy(eth->h_dest, dev->dev_addr, dev->addr_len); - - /* return 0; */ -} - -/* * Function irlan_etc_send_gratuitous_arp (dev) * * Send gratuitous ARP to announce that we have changed @@ -336,17 +326,12 @@ * */ #define HW_MAX_ADDRS 4 /* Must query to get it! */ -void irlan_eth_set_multicast_list(struct net_device *dev) +static void irlan_eth_set_multicast_list(struct net_device *dev) { - struct irlan_cb *self; - - self = dev->priv; + struct irlan_cb *self = netdev_priv(dev); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRLAN_MAGIC, return;); - /* Check if data channel has been connected yet */ if (self->client.state != IRLAN_DATA) { IRDA_DEBUG(1, "%s(), delaying!\n", __FUNCTION__ ); @@ -388,12 +373,9 @@ * Get the current statistics for this device * */ -struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) +static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) { - struct irlan_cb *self = (struct irlan_cb *) dev->priv; - - ASSERT(self != NULL, return NULL;); - ASSERT(self->magic == IRLAN_MAGIC, return NULL;); + struct irlan_cb *self = netdev_priv(dev); return &self->stats; } diff -Nru a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c --- a/net/irda/irlan/irlan_filter.c Sun Apr 18 13:42:41 2004 +++ b/net/irda/irlan/irlan_filter.c Sun Apr 18 13:42:41 2004 @@ -29,12 +29,12 @@ #include /* - * Function handle_filter_request (self, skb) + * Function irlan_filter_request (self, skb) * * Handle filter request from client peer device * */ -void handle_filter_request(struct irlan_cb *self, struct sk_buff *skb) +void irlan_filter_request(struct irlan_cb *self, struct sk_buff *skb) { ASSERT(self != NULL, return;); ASSERT(self->magic == IRLAN_MAGIC, return;); diff -Nru a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c --- a/net/irda/irlan/irlan_provider.c Sun Apr 18 13:42:40 2004 +++ b/net/irda/irlan/irlan_provider.c Sun Apr 18 13:42:40 2004 @@ -358,7 +358,7 @@ 12); break; case CMD_FILTER_OPERATION: - handle_filter_request(self, skb); + irlan_filter_request(self, skb); break; default: IRDA_DEBUG(2, "%s(), Unknown command!\n", __FUNCTION__ ); diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c --- a/net/irda/irlap_event.c Sun Apr 18 13:42:41 2004 +++ b/net/irda/irlap_event.c Sun Apr 18 13:42:41 2004 @@ -2236,6 +2236,14 @@ irlap_disconnect_indication(self, LAP_DISC_INDICATION); break; case RECV_DM_RSP: + /* IrLAP-1.1 p.82: in SCLOSE, S and I type RSP frames + * shall take us down into default NDM state, like DM_RSP + */ + case RECV_RR_RSP: + case RECV_RNR_RSP: + case RECV_REJ_RSP: + case RECV_SREJ_RSP: + case RECV_I_RSP: /* Always switch state before calling upper layers */ irlap_next_state(self, LAP_NDM); @@ -2253,6 +2261,17 @@ irlap_disconnect_indication(self, LAP_DISC_INDICATION); break; default: + /* IrLAP-1.1 p.82: in SCLOSE, basically any received frame + * with pf=1 shall restart the wd-timer and resend the rd:rsp + */ + if (info != NULL && info->pf) { + del_timer(&self->wd_timer); + irlap_wait_min_turn_around(self, &self->qos_tx); + irlap_send_rd_frame(self); + irlap_start_wd_timer(self, self->wd_timeout); + break; /* stay in SCLOSE */ + } + IRDA_DEBUG(1, "%s(), Unknown event %d, (%s)\n", __FUNCTION__, event, irlap_event[event]); diff -Nru a/net/key/af_key.c b/net/key/af_key.c --- a/net/key/af_key.c Sun Apr 18 13:42:40 2004 +++ b/net/key/af_key.c Sun Apr 18 13:42:40 2004 @@ -2636,7 +2636,7 @@ addr->sadb_address_len = (sizeof(struct sadb_address)+sockaddr_size)/ sizeof(uint64_t); - addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; if (x->props.family == AF_INET) { diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c --- a/net/netrom/af_netrom.c Sun Apr 18 13:42:41 2004 +++ b/net/netrom/af_netrom.c Sun Apr 18 13:42:41 2004 @@ -1200,17 +1200,11 @@ } case SIOCGSTAMP: - if (sk != NULL) { - if (!sk->sk_stamp.tv_sec) { - release_sock(sk); - return -ENOENT; - } - ret = copy_to_user((void *)arg, &sk->sk_stamp, sizeof(struct timeval)) ? -EFAULT : 0; - release_sock(sk); - return ret; - } + ret = -EINVAL; + if (sk != NULL) + ret = sock_get_timestamp(sk, (struct timeval *)arg); release_sock(sk); - return -EINVAL; + return ret; case SIOCGIFADDR: case SIOCSIFADDR: diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c --- a/net/packet/af_packet.c Sun Apr 18 13:42:41 2004 +++ b/net/packet/af_packet.c Sun Apr 18 13:42:41 2004 @@ -625,6 +625,10 @@ h->tp_snaplen = snaplen; h->tp_mac = macoff; h->tp_net = netoff; + if (skb->stamp.tv_sec == 0) { + do_gettimeofday(&skb->stamp); + sock_enable_timestamp(sk); + } h->tp_sec = skb->stamp.tv_sec; h->tp_usec = skb->stamp.tv_usec; @@ -1461,13 +1465,8 @@ return put_user(amount, (int *)arg); } case SIOCGSTAMP: - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - if (copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval))) - return -EFAULT; - break; - + return sock_get_timestamp(sk, (struct timeval *)arg); + #ifdef CONFIG_INET case SIOCADDRT: case SIOCDELRT: diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c --- a/net/rose/af_rose.c Sun Apr 18 13:42:41 2004 +++ b/net/rose/af_rose.c Sun Apr 18 13:42:41 2004 @@ -1269,12 +1269,8 @@ } case SIOCGSTAMP: - if (sk != NULL) { - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - return copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; - } + if (sk != NULL) + return sock_get_timestamp(sk, (struct timeval *)arg); return -EINVAL; case SIOCGIFADDR: diff -Nru a/net/rxrpc/transport.c b/net/rxrpc/transport.c --- a/net/rxrpc/transport.c Sun Apr 18 13:42:41 2004 +++ b/net/rxrpc/transport.c Sun Apr 18 13:42:41 2004 @@ -341,6 +341,11 @@ msg->trans = trans; msg->state = RXRPC_MSG_RECEIVED; msg->stamp = pkt->stamp; + if (msg->stamp.tv_sec == 0) { + do_gettimeofday(&msg->stamp); + if (pkt->sk) + sock_enable_timestamp(pkt->sk); + } msg->seq = ntohl(msg->hdr.seq); /* attach the packet */ diff -Nru a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c --- a/net/sched/sch_dsmark.c Sun Apr 18 13:42:40 2004 +++ b/net/sched/sch_dsmark.c Sun Apr 18 13:42:40 2004 @@ -326,7 +326,8 @@ __u16 tmp; DPRINTK("dsmark_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt); - if (rtattr_parse(tb,TCA_DSMARK_MAX,RTA_DATA(opt),RTA_PAYLOAD(opt)) < 0 || + if (!opt || + rtattr_parse(tb,TCA_DSMARK_MAX,RTA_DATA(opt),RTA_PAYLOAD(opt)) < 0 || !tb[TCA_DSMARK_INDICES-1] || RTA_PAYLOAD(tb[TCA_DSMARK_INDICES-1]) < sizeof(__u16)) return -EINVAL; diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c --- a/net/sctp/associola.c Sun Apr 18 13:42:40 2004 +++ b/net/sctp/associola.c Sun Apr 18 13:42:40 2004 @@ -1,5 +1,5 @@ /* SCTP kernel reference Implementation - * (C) Copyright IBM Corp. 2001, 2003 + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001 Intel Corp. @@ -276,7 +276,7 @@ asoc->need_ecne = 0; - asoc->eyecatcher = SCTP_ASSOC_EYECATCHER; + asoc->assoc_id = (sctp_assoc_t)-1; /* Assume that peer would support both address types unless we are * told otherwise. @@ -360,8 +360,6 @@ sctp_transport_free(transport); } - asoc->eyecatcher = 0; - /* Free any cached ASCONF_ACK chunk. */ if (asoc->addip_last_asconf_ack) sctp_chunk_free(asoc->addip_last_asconf_ack); @@ -381,6 +379,12 @@ sctp_endpoint_put(asoc->ep); sock_put(asoc->base.sk); + if ((int)asoc->assoc_id != -1) { + spin_lock_bh(&sctp_assocs_id_lock); + idr_remove(&sctp_assocs_id, (int)asoc->assoc_id); + spin_unlock_bh(&sctp_assocs_id_lock); + } + if (asoc->base.malloced) { kfree(asoc); SCTP_DBG_OBJCNT_DEC(assoc); @@ -856,26 +860,6 @@ return transport; } -/* Is this a live association structure. */ -int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc) -{ - - /* First, verify that this is a kernel address. */ - if (!sctp_is_valid_kaddr((unsigned long) asoc)) - return 0; - - /* Verify that this _is_ an sctp_association - * data structure and if so, that the socket matches. - */ - if (SCTP_ASSOC_EYECATCHER != asoc->eyecatcher) - return 0; - if (asoc->base.sk != sk) - return 0; - - /* The association is valid. */ - return 1; -} - /* Do delayed input processing. This is scheduled by sctp_rcv(). */ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) { @@ -891,6 +875,7 @@ sk = asoc->base.sk; inqueue = &asoc->base.inqueue; + sctp_association_hold(asoc); while (NULL != (chunk = sctp_inq_pop(inqueue))) { state = asoc->state; subtype = chunk->chunk_hdr->type; @@ -913,14 +898,14 @@ /* Check to see if the association is freed in response to * the incoming chunk. If so, get out of the while loop. */ - if (!sctp_assoc_valid(sk, asoc)) + if (asoc->base.dead) break; /* If there is an error on chunk, discard this packet. */ if (error && chunk) chunk->pdiscard = 1; } - + sctp_association_put(asoc); } /* This routine moves an association from its old sk to a new sk. */ diff -Nru a/net/sctp/input.c b/net/sctp/input.c --- a/net/sctp/input.c Sun Apr 18 13:42:40 2004 +++ b/net/sctp/input.c Sun Apr 18 13:42:40 2004 @@ -175,6 +175,12 @@ rcvr = asoc ? &asoc->base : &ep->base; sk = rcvr->sk; + /* SCTP seems to always need a timestamp right now (FIXME) */ + if (skb->stamp.tv_sec == 0) { + do_gettimeofday(&skb->stamp); + sock_enable_timestamp(sk); + } + if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family)) goto discard_release; diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c --- a/net/sctp/ipv6.c Sun Apr 18 13:42:41 2004 +++ b/net/sctp/ipv6.c Sun Apr 18 13:42:41 2004 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2002, 2004 * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll - * Copyright (c) 2002-2003 International Business Machines, Corp. * Copyright (c) 2002-2003 Intel Corp. * * This file is part of the SCTP kernel reference Implementation @@ -698,7 +698,7 @@ union sctp_addr *addr; struct sctp_association *asoc; - asoc = event->sndrcvinfo.sinfo_assoc_id; + asoc = event->asoc; sctp_inet6_msgname(msgname, addrlen); sin6 = (struct sockaddr_in6 *)msgname; sin6->sin6_port = htons(asoc->peer.port); diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c --- a/net/sctp/objcnt.c Sun Apr 18 13:42:40 2004 +++ b/net/sctp/objcnt.c Sun Apr 18 13:42:40 2004 @@ -1,5 +1,5 @@ /* SCTP kernel reference Implementation - * Copyright (c) 2001 International Business Machines Corp. + * (C) Copyright IBM Corp. 2001, 2004 * * This file is part of the SCTP kernel reference Implementation * @@ -134,7 +134,7 @@ /* Cleanup the objcount entry in the proc filesystem. */ void sctp_dbg_objcnt_exit(void) { - remove_proc_entry("sctp_dbg_objcount", proc_net_sctp); + remove_proc_entry("sctp_dbg_objcnt", proc_net_sctp); } diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c --- a/net/sctp/protocol.c Sun Apr 18 13:42:41 2004 +++ b/net/sctp/protocol.c Sun Apr 18 13:42:41 2004 @@ -64,6 +64,9 @@ struct proc_dir_entry *proc_net_sctp; DEFINE_SNMP_STAT(struct sctp_mib, sctp_statistics); +struct idr sctp_assocs_id; +spinlock_t sctp_assocs_id_lock = SPIN_LOCK_UNLOCKED; + /* This is the global socket data structure used for responding to * the Out-of-the-blue (OOTB) packets. A control sock will be created * for this socket at the initialization time. @@ -721,7 +724,7 @@ if (msgname) { struct sctp_association *asoc; - asoc = event->sndrcvinfo.sinfo_assoc_id; + asoc = event->asoc; sctp_inet_msgname(msgname, addr_len); sin = (struct sockaddr_in *)msgname; sinfrom = &asoc->peer.primary_addr.v4; @@ -1048,6 +1051,9 @@ /* Initialize default stream count setup information. */ sctp_max_instreams = SCTP_DEFAULT_INSTREAMS; sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS; + + /* Initialize handle used for association ids. */ + idr_init(&sctp_assocs_id); /* Size and allocate the association hash table. * The methodology is similar to that of the tcp hash tables. diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c --- a/net/sctp/sm_make_chunk.c Sun Apr 18 13:42:40 2004 +++ b/net/sctp/sm_make_chunk.c Sun Apr 18 13:42:40 2004 @@ -1,5 +1,5 @@ /* SCTP kernel reference Implementation - * (C) Copyright IBM Corp. 2001, 2003 + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 2001-2002 Intel Corp. @@ -1817,10 +1817,23 @@ /* Allocate storage for the negotiated streams if it is not a temporary * association. */ if (!asoc->temp) { + sctp_assoc_t assoc_id; + asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams, asoc->c.sinit_num_ostreams, gfp); if (!asoc->ssnmap) - goto nomem_ssnmap; + goto clean_up; + + do { + if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp))) + goto clean_up; + spin_lock_bh(&sctp_assocs_id_lock); + assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id, + (void *)asoc); + spin_unlock_bh(&sctp_assocs_id_lock); + } while (unlikely((int)assoc_id == -1)); + + asoc->assoc_id = assoc_id; } /* ADDIP Section 4.1 ASCONF Chunk Procedures @@ -1836,7 +1849,6 @@ asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1; return 1; -nomem_ssnmap: clean_up: /* Release the transport structures. */ list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c --- a/net/sctp/socket.c Sun Apr 18 13:42:41 2004 +++ b/net/sctp/socket.c Sun Apr 18 13:42:41 2004 @@ -135,8 +135,14 @@ } /* Otherwise this is a UDP-style socket. */ - asoc = (struct sctp_association *)id; - if (!sctp_assoc_valid(sk, asoc)) + if (!id || (id == (sctp_assoc_t)-1)) + return NULL; + + spin_lock_bh(&sctp_assocs_id_lock); + asoc = (struct sctp_association *)idr_find(&sctp_assocs_id, (int)id); + spin_unlock_bh(&sctp_assocs_id_lock); + + if (!asoc || (asoc->base.sk != sk) || asoc->base.dead) return NULL; return asoc; @@ -1010,7 +1016,7 @@ struct list_head *pos; int msg_flags = msg->msg_flags; - SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %u)\n", + SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %zu)\n", sk, msg, msg_len); err = 0; @@ -1066,7 +1072,7 @@ associd = sinfo->sinfo_assoc_id; } - SCTP_DEBUG_PRINTK("msg_len: %u, sinfo_flags: 0x%x\n", + SCTP_DEBUG_PRINTK("msg_len: %zu, sinfo_flags: 0x%x\n", msg_len, sinfo_flags); /* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */ @@ -1432,7 +1438,7 @@ int err = 0; int skb_len; - SCTP_DEBUG_PRINTK("sctp_recvmsg(%s: %p, %s: %p, %s: %d, %s: %d, %s: " + SCTP_DEBUG_PRINTK("sctp_recvmsg(%s: %p, %s: %p, %s: %zd, %s: %d, %s: " "0x%x, %s: %p)\n", "sk", sk, "msghdr", msg, "len", len, "knoblauch", noblock, "flags", flags, "addr_len", addr_len); @@ -1498,8 +1504,7 @@ * rwnd by that amount. If all the data in the skb is read, * rwnd is updated when the event is freed. */ - sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id, - copied); + sctp_assoc_rwnd_increase(event->asoc, copied); goto out; } else if ((event->msg_flags & MSG_NOTIFICATION) || (event->msg_flags & MSG_EOR)) @@ -4233,7 +4238,7 @@ long current_timeo = *timeo_p; DEFINE_WAIT(wait); - SCTP_DEBUG_PRINTK("wait_for_sndbuf: asoc=%p, timeo=%ld, msg_len=%u\n", + SCTP_DEBUG_PRINTK("wait_for_sndbuf: asoc=%p, timeo=%ld, msg_len=%zu\n", asoc, (long)(*timeo_p), msg_len); /* Increment the association's refcnt. */ @@ -4477,7 +4482,7 @@ */ sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { event = sctp_skb2event(skb); - if (event->sndrcvinfo.sinfo_assoc_id == assoc) { + if (event->asoc == assoc) { __skb_unlink(skb, skb->list); __skb_queue_tail(&newsk->sk_receive_queue, skb); } @@ -4506,7 +4511,7 @@ */ sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { event = sctp_skb2event(skb); - if (event->sndrcvinfo.sinfo_assoc_id == assoc) { + if (event->asoc == assoc) { __skb_unlink(skb, skb->list); __skb_queue_tail(queue, skb); } diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c --- a/net/sctp/ulpevent.c Sun Apr 18 13:42:40 2004 +++ b/net/sctp/ulpevent.c Sun Apr 18 13:42:40 2004 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -590,8 +590,7 @@ struct sctp_chunk *chunk, int gfp) { - struct sctp_ulpevent *event; - struct sctp_sndrcvinfo *info; + struct sctp_ulpevent *event = NULL; struct sk_buff *skb; size_t padding, len; @@ -624,101 +623,21 @@ /* Initialize event with flags 0. */ sctp_ulpevent_init(event, 0); - event->iif = sctp_chunk_iif(chunk); - sctp_ulpevent_receive_data(event, asoc); - info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo; - - /* Sockets API Extensions for SCTP - * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) - * - * sinfo_stream: 16 bits (unsigned integer) - * - * For recvmsg() the SCTP stack places the message's stream number in - * this value. - */ - info->sinfo_stream = ntohs(chunk->subh.data_hdr->stream); - - /* Sockets API Extensions for SCTP - * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) - * - * sinfo_ssn: 16 bits (unsigned integer) - * - * For recvmsg() this value contains the stream sequence number that - * the remote endpoint placed in the DATA chunk. For fragmented - * messages this is the same number for all deliveries of the message - * (if more than one recvmsg() is needed to read the message). - */ - info->sinfo_ssn = ntohs(chunk->subh.data_hdr->ssn); - - /* Sockets API Extensions for SCTP - * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) - * - * sinfo_ppid: 32 bits (unsigned integer) - * - * In recvmsg() this value is - * the same information that was passed by the upper layer in the peer - * application. Please note that byte order issues are NOT accounted - * for and this information is passed opaquely by the SCTP stack from - * one end to the other. - */ - info->sinfo_ppid = chunk->subh.data_hdr->ppid; - - /* Sockets API Extensions for SCTP - * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) - * - * sinfo_flags: 16 bits (unsigned integer) - * - * This field may contain any of the following flags and is composed of - * a bitwise OR of these values. - * - * recvmsg() flags: - * - * MSG_UNORDERED - This flag is present when the message was sent - * non-ordered. - */ + event->stream = ntohs(chunk->subh.data_hdr->stream); + event->ssn = ntohs(chunk->subh.data_hdr->ssn); + event->ppid = chunk->subh.data_hdr->ppid; if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { - info->sinfo_flags |= MSG_UNORDERED; - - /* sinfo_cumtsn: 32 bit (unsigned integer) - * - * This field will hold the current cumulative TSN as - * known by the underlying SCTP layer. Note this field is - * ignored when sending and only valid for a receive - * operation when sinfo_flags are set to MSG_UNORDERED. - */ - info->sinfo_cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); + event->flags |= MSG_UNORDERED; + event->cumtsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map); } - - /* Note: For reassembly, we need to have the fragmentation bits. - * For now, merge these into the msg_flags, since those bit - * possitions are not used. - */ + event->tsn = ntohl(chunk->subh.data_hdr->tsn); event->msg_flags |= chunk->chunk_hdr->flags; - - /* With 04 draft, tsn moves into sndrcvinfo. */ - info->sinfo_tsn = ntohl(chunk->subh.data_hdr->tsn); - - /* Context is not used on receive. */ - info->sinfo_context = 0; - - /* Sockets API Extensions for SCTP - * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) - * - * sinfo_assoc_id: sizeof (sctp_assoc_t) - * - * The association handle field, sinfo_assoc_id, holds the identifier - * for the association announced in the COMMUNICATION_UP notification. - * All notifications for a given association have the same identifier. - * Ignored for TCP-style sockets. - */ - info->sinfo_assoc_id = sctp_assoc2id(asoc); - - return event; + event->iif = sctp_chunk_iif(chunk); fail: - return NULL; + return event; } /* Create a partial delivery related event. @@ -797,11 +716,77 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, struct msghdr *msghdr) { - if (!sctp_ulpevent_is_notification(event)) { - put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, - sizeof(struct sctp_sndrcvinfo), - (void *) &event->sndrcvinfo); - } + struct sctp_sndrcvinfo sinfo; + + if (sctp_ulpevent_is_notification(event)) + return; + + /* Sockets API Extensions for SCTP + * Section 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV) + * + * sinfo_stream: 16 bits (unsigned integer) + * + * For recvmsg() the SCTP stack places the message's stream number in + * this value. + */ + sinfo.sinfo_stream = event->stream; + /* sinfo_ssn: 16 bits (unsigned integer) + * + * For recvmsg() this value contains the stream sequence number that + * the remote endpoint placed in the DATA chunk. For fragmented + * messages this is the same number for all deliveries of the message + * (if more than one recvmsg() is needed to read the message). + */ + sinfo.sinfo_ssn = event->ssn; + /* sinfo_ppid: 32 bits (unsigned integer) + * + * In recvmsg() this value is + * the same information that was passed by the upper layer in the peer + * application. Please note that byte order issues are NOT accounted + * for and this information is passed opaquely by the SCTP stack from + * one end to the other. + */ + sinfo.sinfo_ppid = event->ppid; + /* sinfo_flags: 16 bits (unsigned integer) + * + * This field may contain any of the following flags and is composed of + * a bitwise OR of these values. + * + * recvmsg() flags: + * + * MSG_UNORDERED - This flag is present when the message was sent + * non-ordered. + */ + sinfo.sinfo_flags = event->flags; + /* sinfo_tsn: 32 bit (unsigned integer) + * + * For the receiving side, this field holds a TSN that was + * assigned to one of the SCTP Data Chunks. + */ + sinfo.sinfo_tsn = event->tsn; + /* sinfo_cumtsn: 32 bit (unsigned integer) + * + * This field will hold the current cumulative TSN as + * known by the underlying SCTP layer. Note this field is + * ignored when sending and only valid for a receive + * operation when sinfo_flags are set to MSG_UNORDERED. + */ + sinfo.sinfo_cumtsn = event->cumtsn; + /* sinfo_assoc_id: sizeof (sctp_assoc_t) + * + * The association handle field, sinfo_assoc_id, holds the identifier + * for the association announced in the COMMUNICATION_UP notification. + * All notifications for a given association have the same identifier. + * Ignored for one-to-one style sockets. + */ + sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); + + /* These fields are not used while receiving. */ + sinfo.sinfo_context = 0; + sinfo.sinfo_timetolive = 0; + + put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, + sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); } /* Stub skb destructor. */ @@ -831,14 +816,14 @@ sctp_association_hold((struct sctp_association *)asoc); skb = sctp_event2skb(event); skb->sk = asoc->base.sk; - event->sndrcvinfo.sinfo_assoc_id = sctp_assoc2id(asoc); + event->asoc = (struct sctp_association *)asoc; skb->destructor = sctp_stub_rfree; } /* A simple destructor to give up the reference to the association. */ static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) { - sctp_association_put(event->sndrcvinfo.sinfo_assoc_id); + sctp_association_put(event->asoc); } /* Do accounting for bytes received and hold a reference to the association @@ -880,8 +865,7 @@ */ skb = sctp_event2skb(event); - sctp_assoc_rwnd_increase(event->sndrcvinfo.sinfo_assoc_id, - skb_headlen(skb)); + sctp_assoc_rwnd_increase(event->asoc, skb_headlen(skb)); /* Don't forget the fragments. */ for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) { diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c --- a/net/sctp/ulpqueue.c Sun Apr 18 13:42:41 2004 +++ b/net/sctp/ulpqueue.c Sun Apr 18 13:42:41 2004 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation + * (C) Copyright IBM Corp. 2001, 2004 * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * Copyright (c) 2001 Nokia, Inc. * Copyright (c) 2001 La Monte H.P. Yarroll @@ -251,7 +251,7 @@ struct sctp_ulpevent *cevent; __u32 tsn, ctsn; - tsn = event->sndrcvinfo.sinfo_tsn; + tsn = event->tsn; /* See if it belongs at the end. */ pos = skb_peek_tail(&ulpq->reasm); @@ -262,7 +262,7 @@ /* Short circuit just dropping it at the end. */ cevent = sctp_skb2event(pos); - ctsn = cevent->sndrcvinfo.sinfo_tsn; + ctsn = cevent->tsn; if (TSN_lt(ctsn, tsn)) { __skb_queue_tail(&ulpq->reasm, sctp_event2skb(event)); return; @@ -271,7 +271,7 @@ /* Find the right place in this list. We store them by TSN. */ skb_queue_walk(&ulpq->reasm, pos) { cevent = sctp_skb2event(pos); - ctsn = cevent->sndrcvinfo.sinfo_tsn; + ctsn = cevent->tsn; if (TSN_lt(tsn, ctsn)) break; @@ -368,7 +368,7 @@ */ skb_queue_walk(&ulpq->reasm, pos) { cevent = sctp_skb2event(pos); - ctsn = cevent->sndrcvinfo.sinfo_tsn; + ctsn = cevent->tsn; switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { case SCTP_DATA_FIRST_FRAG: @@ -425,7 +425,7 @@ skb_queue_walk(&ulpq->reasm, pos) { cevent = sctp_skb2event(pos); - ctsn = cevent->sndrcvinfo.sinfo_tsn; + ctsn = cevent->tsn; switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { case SCTP_DATA_MIDDLE_FRAG: @@ -486,7 +486,7 @@ /* Do not even bother unless this is the next tsn to * be delivered. */ - ctsn = event->sndrcvinfo.sinfo_tsn; + ctsn = event->tsn; ctsnap = sctp_tsnmap_get_ctsn(&ulpq->asoc->peer.tsn_map); if (TSN_lte(ctsn, ctsnap)) retval = sctp_ulpq_retrieve_partial(ulpq); @@ -517,7 +517,7 @@ skb_queue_walk(&ulpq->reasm, pos) { cevent = sctp_skb2event(pos); - ctsn = cevent->sndrcvinfo.sinfo_tsn; + ctsn = cevent->tsn; switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) { case SCTP_DATA_FIRST_FRAG: @@ -563,15 +563,15 @@ __u16 sid, csid; __u16 ssn, cssn; - sid = event->sndrcvinfo.sinfo_stream; - ssn = event->sndrcvinfo.sinfo_ssn; + sid = event->stream; + ssn = event->ssn; in = &ulpq->asoc->ssnmap->in; /* We are holding the chunks by stream, by SSN. */ sctp_skb_for_each(pos, &ulpq->lobby, tmp) { cevent = (struct sctp_ulpevent *) pos->cb; - csid = cevent->sndrcvinfo.sinfo_stream; - cssn = cevent->sndrcvinfo.sinfo_ssn; + csid = cevent->stream; + cssn = cevent->ssn; /* Have we gone too far? */ if (csid > sid) @@ -609,12 +609,12 @@ return; } - sid = event->sndrcvinfo.sinfo_stream; - ssn = event->sndrcvinfo.sinfo_ssn; + sid = event->stream; + ssn = event->ssn; cevent = (struct sctp_ulpevent *) pos->cb; - csid = cevent->sndrcvinfo.sinfo_stream; - cssn = cevent->sndrcvinfo.sinfo_ssn; + csid = cevent->stream; + cssn = cevent->ssn; if (sid > csid) { __skb_queue_tail(&ulpq->lobby, sctp_event2skb(event)); return; @@ -630,8 +630,8 @@ */ skb_queue_walk(&ulpq->lobby, pos) { cevent = (struct sctp_ulpevent *) pos->cb; - csid = cevent->sndrcvinfo.sinfo_stream; - cssn = cevent->sndrcvinfo.sinfo_ssn; + csid = cevent->stream; + cssn = cevent->ssn; if (csid > sid) break; @@ -656,8 +656,8 @@ return event; /* Note: The stream ID must be verified before this routine. */ - sid = event->sndrcvinfo.sinfo_stream; - ssn = event->sndrcvinfo.sinfo_ssn; + sid = event->stream; + ssn = event->ssn; in = &ulpq->asoc->ssnmap->in; /* Is this the expected SSN for this stream ID? */ @@ -694,7 +694,7 @@ while ((skb = __skb_dequeue_tail(&ulpq->lobby))) { freed += skb_headlen(skb); event = sctp_skb2event(skb); - tsn = event->sndrcvinfo.sinfo_tsn; + tsn = event->tsn; sctp_ulpevent_free(event); sctp_tsnmap_renege(tsnmap, tsn); @@ -720,7 +720,7 @@ while ((skb = __skb_dequeue_tail(&ulpq->reasm))) { freed += skb_headlen(skb); event = sctp_skb2event(skb); - tsn = event->sndrcvinfo.sinfo_tsn; + tsn = event->tsn; sctp_ulpevent_free(event); sctp_tsnmap_renege(tsnmap, tsn); diff -Nru a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c --- a/net/sunrpc/auth_gss/svcauth_gss.c Sun Apr 18 13:42:41 2004 +++ b/net/sunrpc/auth_gss/svcauth_gss.c Sun Apr 18 13:42:41 2004 @@ -895,6 +895,7 @@ svc_putu32(resv, rpc_success); goto complete; case RPC_GSS_PROC_DATA: + *authp = rpc_autherr_badcred; rqstp->rq_client = find_gss_auth_domain(rsci->mechctx, gc->gc_svc); if (rqstp->rq_client == NULL) diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Sun Apr 18 13:42:40 2004 +++ b/net/sunrpc/svcsock.c Sun Apr 18 13:42:40 2004 @@ -591,6 +591,12 @@ /* possibly an icmp error */ dprintk("svc: recvfrom returned error %d\n", -err); } + if (skb->stamp.tv_sec == 0) { + skb->stamp.tv_sec = xtime.tv_sec; + skb->stamp.tv_usec = xtime.tv_nsec * 1000; + /* Don't enable netstamp, sunrpc doesn't + need that much accuracy */ + } svsk->sk_sk->sk_stamp = skb->stamp; set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */ diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c --- a/net/unix/af_unix.c Sun Apr 18 13:42:41 2004 +++ b/net/unix/af_unix.c Sun Apr 18 13:42:41 2004 @@ -82,8 +82,6 @@ * with BSD names. */ -#undef unix /* KBUILD_MODNAME */ - #include #include #include diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c --- a/net/wanrouter/af_wanpipe.c Sun Apr 18 13:42:41 2004 +++ b/net/wanrouter/af_wanpipe.c Sun Apr 18 13:42:41 2004 @@ -1765,13 +1765,7 @@ switch(cmd) { case SIOCGSTAMP: - if (!sk->sk_stamp.tv_sec) - return -ENOENT; - err = -EFAULT; - if (!copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval))) - err = 0; - return err; + return sock_get_timestamp(sk, (struct timeval *)arg); case SIOC_WANPIPE_CHECK_TX: diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c --- a/net/x25/af_x25.c Sun Apr 18 13:42:41 2004 +++ b/net/x25/af_x25.c Sun Apr 18 13:42:41 2004 @@ -1206,14 +1206,10 @@ } case SIOCGSTAMP: - if (sk) { - rc = -ENOENT; - if (!sk->sk_stamp.tv_sec) - break; - rc = copy_to_user((void *)arg, &sk->sk_stamp, - sizeof(struct timeval)) ? -EFAULT : 0; - } rc = -EINVAL; + if (sk) + rc = sock_get_timestamp(sk, + (struct timeval *)arg); break; case SIOCGIFADDR: case SIOCSIFADDR: diff -Nru a/scripts/modpost.c b/scripts/modpost.c --- a/scripts/modpost.c Sun Apr 18 13:42:40 2004 +++ b/scripts/modpost.c Sun Apr 18 13:42:40 2004 @@ -487,6 +487,7 @@ buf_printf(b, "\n"); buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); buf_printf(b, "\n"); + buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */ buf_printf(b, "struct module __this_module\n"); buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n"); diff -Nru a/sound/core/Kconfig b/sound/core/Kconfig --- a/sound/core/Kconfig Sun Apr 18 13:42:41 2004 +++ b/sound/core/Kconfig Sun Apr 18 13:42:41 2004 @@ -1,7 +1,7 @@ # ALSA soundcard-configuration config SND_BIT32_EMUL tristate "Emulation for 32-bit applications" - depends on SND && (SPARC64 || PPC64 || X86_64 && IA32_EMULATION) + depends on SND && SND_PCM && (SPARC64 || PPC64 || X86_64 && IA32_EMULATION) config SND_TIMER tristate