# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/03/07 19:28:25-05:00 khc@pm.waw.pl # [PATCH] 2.6.x wanXL driver update # # The attached patch updates wanXL card driver. Please apply to Linux 2.6. # Thanks. # # Changes: # * fixed initialization kernel panic, introduced with recent alloc_netdev() # wan patch, # * wanxl_rx_intr() port# now checked before accessing port structure, # * cleanups etc. # -- # Krzysztof Halasa, B*FH # # drivers/net/wan/wanxl.c # 2004/03/07 16:50:38-05:00 khc@pm.waw.pl +87 -100 # 2.6.x wanXL driver update # # ChangeSet # 2004/03/07 19:28:18-05:00 scott.feldman@intel.com # [PATCH] missing setup for National DP83840 PHY rev b/c # # * Add National DP83840 PHY rev b/c setup. Only rev a was being setup. # # drivers/net/e100.c # 2004/03/04 12:30:48-05:00 scott.feldman@intel.com +4 -3 # missing setup for National DP83840 PHY rev b/c # # ChangeSet # 2004/03/07 19:28:10-05:00 akpm@osdl.org # [PATCH] tulip printk cleanup # # From: Joe Perches # # Use %08llx for a dma_addr_t, not the recently-added %llx. # # drivers/net/tulip/interrupt.c # 2004/03/06 00:22:14-05:00 akpm@osdl.org +1 -1 # tulip printk cleanup # # ChangeSet # 2004/03/07 08:02:56-08:00 axboe@suse.de # [PATCH] add blk_queue_stopped() helper function # # The carmel driver will want to use this rather # than muck around in queue internals directly. # # include/linux/blkdev.h # 2004/03/07 03:49:12-08:00 axboe@suse.de +2 -0 # add blk_queue_stopped() helper function # # ChangeSet # 2004/03/07 08:02:47-08:00 akpm@osdl.org # [PATCH] arc4.c compile fix for older gcc's # # Declarations come before statements, please. # # Current gcc warns about this too, bless them: # # crypto/arc4.c: In function `arc4_crypt': # crypto/arc4.c:65: warning: ISO C90 forbids mixed declarations and code # # crypto/arc4.c # 2004/03/07 02:22:38-08:00 akpm@osdl.org +3 -2 # arc4.c compile fix for older gcc's # # ChangeSet # 2004/03/07 00:52:03-08:00 akpm@osdl.org # [PATCH] floppy oops fix # # From: Zwane Mwaikambo # # It looks like a block request snuck through before we had initialised the # motor_off_timer timers. So I pushed the timer init earlier. # # drivers/block/floppy.c # 2004/03/06 23:22:15-08:00 akpm@osdl.org +9 -10 # floppy oops fix # # ChangeSet # 2004/03/07 00:51:53-08:00 akpm@osdl.org # [PATCH] OSS Sound Driver Forte needs ac97_codec # # From: Marc-Christian Petersen # # OSS Sound Driver Forte needs ac97_codec. # # sound/oss/Makefile # 2004/03/06 23:17:44-08:00 akpm@osdl.org +1 -1 # OSS Sound Driver Forte needs ac97_codec # # ChangeSet # 2004/03/07 00:51:43-08:00 akpm@osdl.org # [PATCH] fix i2c compile warnings # # drivers/i2c/busses/i2c-elv.c: In function `i2c_bitelv_init': # # drivers/i2c/busses/i2c-elv.c:155: warning: unsigned int format, long int arg (arg 2) # drivers/i2c/busses/i2c-elv.c:155: warning: unsigned int format, long int arg (arg 2) # drivers/i2c/busses/i2c-velleman.c: In function `i2c_bitvelle_init': # drivers/i2c/busses/i2c-velleman.c:141: warning: unsigned int format, long int arg (arg 2) # drivers/i2c/busses/i2c-velleman.c:141: warning: unsigned int format, long int arg (arg 2) # # drivers/i2c/busses/i2c-velleman.c # 2004/03/06 23:17:43-08:00 akpm@osdl.org +1 -1 # fix i2c compile warnings # # drivers/i2c/busses/i2c-elv.c # 2004/03/06 23:17:43-08:00 akpm@osdl.org +1 -1 # fix i2c compile warnings # # ChangeSet # 2004/03/07 00:51:32-08:00 akpm@osdl.org # [PATCH] Documentation/cdrom/ide-cd fix # # From: David Joerg # # Fix the description of the IO ports for the IDE primary and secondary # interfaces. # # Documentation/cdrom/ide-cd # 2004/03/06 23:17:11-08:00 akpm@osdl.org +3 -3 # Documentation/cdrom/ide-cd fix # # ChangeSet # 2004/03/07 00:51:22-08:00 akpm@osdl.org # [PATCH] alpha ptrace race fix # # From: Aneesh Kumar KV # # We need to set the tasks's exit code prior to waking it, not afterwards. # # Acked by rth. # # arch/alpha/kernel/ptrace.c # 2004/03/06 23:16:12-08:00 akpm@osdl.org +1 -1 # alpha ptrace race fix # # ChangeSet # 2004/03/07 00:51:13-08:00 akpm@osdl.org # [PATCH] Fix nobh_prepare_write() race # # Dave Kleikamp points out a race between # nobh_prepare_write() and end_buffer_read_sync(). end_buffer_read_sync() # calls unlock_buffer(), waking the nobh_prepare_write() thread, which # immediately frees the buffer_head. end_buffer_read_sync() then calls # put_bh() which decrements b_count for the already freed structure. The # SLAB_DEBUG code detects the slab corruption. # # We fix this by giving nobh_prepare_write() a private buffer_head end_o # handler which doesn't touch the buffer's contents after unlocking it. # # fs/buffer.c # 2004/03/06 23:16:11-08:00 akpm@osdl.org +39 -4 # Fix nobh_prepare_write() race # # ChangeSet # 2004/03/07 00:51:03-08:00 akpm@osdl.org # [PATCH] CONFIG_LBD fixes # # From: Eric Sandeen # # Several functions in buffer.c are using unsigned long where they should be # using sector_t. # # Also, use pgoff_t in several places so it is easier to tell what is beingused # as a pagecache index, what is being used as a disk index and what is being # used as an offset-into-page. # # fs/buffer.c # 2004/03/06 23:30:56-08:00 akpm@osdl.org +14 -12 # CONFIG_LBD fixes # # ChangeSet # 2004/03/07 00:50:53-08:00 akpm@osdl.org # [PATCH] fix oops in emu10k1_wavein_open() error recovery # # If a large pci_alloc_consistent() GFP_ATOMIC allocation fails this driver's # recovery code will call emu10k1_wavein_close() far earlier than it should: it # goes splat in emu10k1_timer_uninstall(). # # Fix it by simply removing that call: we haven't allocated any resources yet # anyway. # # Note that one of the callers of emu10k1_wavein_open(), emu10k1_audio_read() # will sit there stupidly retrying the open. But it has a sleep in there so # something might eventually give way. # # sound/oss/emu10k1/cardwi.c # 2004/03/06 23:16:11-08:00 akpm@osdl.org +0 -1 # fix oops in emu10k1_wavein_open() error recovery # # ChangeSet # 2004/03/07 00:50:43-08:00 akpm@osdl.org # [PATCH] i2o subsystem minor bugfixes # # From: Markus Lidel # # drivers/message/i2o/i2o_block.c: # # - corrected the initialization sequence of the request queues. # # - added initialization to queue spinlocks. # # - release device in i2o_scan because else the device could not be queried. # # - i2o_block event threads wait on signal KILL but signal TERM was sent. # # drivers/message/i2o/i2o_core.c: # # - set the HRT length to 0 at initialization, to avoid calling free on # unallocated memory. # # - i2o_core event threads wait on signal KILL but signal TERM was sent. # # - added a limit of 3 tries to get the HRT from the controller. # # - removed the dpt parameter, which was used to force DPT controllers get # handled by the i2o driver. Now all available i2o controllers will be # handled by this driver. # # drivers/message/i2o/i2o_scsi.c: # # - beautifying of printk calls. # # - added scsi_unregister to properly clean up on module unload. # # drivers/message/i2o/Kconfig: # # - added help for i2o_block and i2o_scsi to describe the differences between # the two drivers. # # include/linux/i2o-dev.h: # # - cleaned typo "tate" into "state". # # include/linux/i2o.h: # # - removed defines from i2o_block and insert it here. # # (Acked by Alan) # # include/linux/i2o.h # 2004/03/06 23:16:10-08:00 akpm@osdl.org +19 -0 # i2o subsystem minor bugfixes # # include/linux/i2o-dev.h # 2004/03/06 23:16:10-08:00 akpm@osdl.org +1 -1 # i2o subsystem minor bugfixes # # drivers/message/i2o/i2o_scsi.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +39 -27 # i2o subsystem minor bugfixes # # drivers/message/i2o/i2o_core.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +34 -32 # i2o subsystem minor bugfixes # # drivers/message/i2o/i2o_block.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +32 -46 # i2o subsystem minor bugfixes # # drivers/message/i2o/Kconfig # 2004/03/06 23:16:10-08:00 akpm@osdl.org +6 -2 # i2o subsystem minor bugfixes # # ChangeSet # 2004/03/07 00:50:34-08:00 akpm@osdl.org # [PATCH] v4l1 compatibility module fix. # # From: Gerd Knorr # # This patch fixes a bug in the v4l1-compat module and makes it pass the # correct buffer type to the v4l2 driver on VIDIOC_STREAM(ON|OFF) ioctls. # # drivers/media/video/v4l1-compat.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +4 -2 # v4l1 compatibility module fix. # # ChangeSet # 2004/03/07 00:50:22-08:00 akpm@osdl.org # [PATCH] add missing MODULE_LICENSEs # # From: Arjan van de Ven # # sound/oss/ac97_plugin_ad1980.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +1 -0 # add missing MODULE_LICENSEs # # drivers/usb/serial/safe_serial.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +1 -0 # add missing MODULE_LICENSEs # # drivers/mtd/maps/map_funcs.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +1 -0 # add missing MODULE_LICENSEs # # drivers/mtd/chips/cfi_cmdset_0020.c # 2004/03/06 23:16:10-08:00 akpm@osdl.org +2 -0 # add missing MODULE_LICENSEs # # ChangeSet # 2004/03/07 00:50:11-08:00 akpm@osdl.org # [PATCH] ext2/ext3 -ENOSPC bug # # From: Chris Mason # # find_group_other looks buggy for ext2 and ext3 in 2.6, it can cause -ENOSPC # errors when the fs has plenty of free room. # # To hit the bug, you need a filesystem where: # # parent_group has no free blocks (but might have free inodes) Every other # group with free inodes has no free blocks. # # That gets you down to the final linear search in find_group_other. The # linear search has two bugs: # # group = parent_group + 1; means we start searching at parent_group + 2 # because the loop increments group before using it. # # for(i = 2 ; i < ngroups ; i++) means we don't search through all the # groups. # # The end result is that parent_group and parent_group + 1 are not checked # for free inodes in the final linear search. ext3 has the same problem. # # fs/ext3/ialloc.c # 2004/03/06 23:16:09-08:00 akpm@osdl.org +2 -2 # ext2/ext3 -ENOSPC bug # # fs/ext2/ialloc.c # 2004/03/06 23:16:09-08:00 akpm@osdl.org +2 -2 # ext2/ext3 -ENOSPC bug # # ChangeSet # 2004/03/07 00:50:01-08:00 akpm@osdl.org # [PATCH] sb16 sample size fix # # From: Andreas Kies # # Fix improperly handled 16 bit sample size. If you use an odd number of # bytes in 16 bit mode the driver fails to work. # # sound/oss/sb_audio.c # 2004/03/06 23:16:09-08:00 akpm@osdl.org +1 -1 # sb16 sample size fix # # ChangeSet # 2004/03/07 00:49:52-08:00 akpm@osdl.org # [PATCH] serial_core.h needs sched.h # # In file included from drivers/misc/ibmasm/uart.c:27: # include/linux/serial_core.h: In function `uart_handle_dcd_change': # include/linux/serial_core.h:407: `TASK_INTERRUPTIBLE' undeclared (first use in this function) # # include/linux/serial_core.h # 2004/03/06 23:16:08-08:00 akpm@osdl.org +1 -0 # serial_core.h needs sched.h # # ChangeSet # 2004/03/07 00:49:42-08:00 akpm@osdl.org # [PATCH] kill a dead function in lockd # # From: Christoph Hellwig # # sleep_on hurts my eyes and this offender is compltely unused, so.. # # fs/lockd/clntproc.c # 2004/03/06 23:14:27-08:00 akpm@osdl.org +0 -13 # kill a dead function in lockd # # ChangeSet # 2004/03/07 00:49:31-08:00 akpm@osdl.org # [PATCH] c99 initializers for cs46xx_wrapper # # From: Arnd Bergmann # # This use of deprecated struct initializers was hidden behind macro magic # and has appearantly not been noticed before. # # sound/oss/cs46xx_wrapper-24.h # 2004/03/06 23:12:57-08:00 akpm@osdl.org +1 -1 # c99 initializers for cs46xx_wrapper # # ChangeSet # 2004/03/07 00:49:21-08:00 akpm@osdl.org # [PATCH] Fix initrd Kconfig dependencies # # From: "Jim Gifford" # # Prevent initrd from being built if ram device is built as a module. # # drivers/block/Kconfig # 2004/03/06 23:12:57-08:00 akpm@osdl.org +1 -0 # Fix initrd Kconfig dependencies # # ChangeSet # 2004/03/07 00:49:11-08:00 akpm@osdl.org # [PATCH] char/rio/rioctrl: fix ioctl return values # # From: "Randy.Dunlap" # # From: Tony Breeds # # It fixes 3 places where the ioctl returns positives instead of negatives. # I've gotten feedback from the maintainer (Rogier Wolff (sp?) and he has no # objections. # # drivers/char/rio/rioctrl.c # 2004/03/06 23:12:56-08:00 akpm@osdl.org +3 -3 # char/rio/rioctrl: fix ioctl return values # # ChangeSet # 2004/03/07 00:49:01-08:00 akpm@osdl.org # [PATCH] fix put_compat_timespec prototype # # From: Arnd Bergmann # # The wrong argument in put_compat_timespec is marked const, causing # unnecessary compiler warnings. # # kernel/compat.c # 2004/03/06 23:05:30-08:00 akpm@osdl.org +1 -1 # fix put_compat_timespec prototype # # include/linux/compat.h # 2004/03/06 23:05:30-08:00 akpm@osdl.org +1 -1 # fix put_compat_timespec prototype # # ChangeSet # 2004/03/07 00:48:52-08:00 akpm@osdl.org # [PATCH] ppc64: Convert mm_context_t to a struct # # From: David Gibson # # Converts the mm_context_t on ppc64 to be a struct. This lets us separate # the low_hpages flag into a separate field rather than folding it into the # actual context id. That makes things neater, since the flag is # conceptually separate and has, for example, should be propogate across a # fork whereas the context ID obviously isn't. The mm_context_id is the only # place to put arch-specific information in the mm_struct. # # This patch will also make some interesting extensions to the hugepage # support much easier, such as allowing dynamic resizing of the hugepage # address space, or using special pagetables for hugepages. # # include/asm-ppc64/page.h # 2004/03/06 23:05:29-08:00 akpm@osdl.org +3 -2 # ppc64: Convert mm_context_t to a struct # # include/asm-ppc64/mmu_context.h # 2004/03/06 23:05:29-08:00 akpm@osdl.org +3 -8 # ppc64: Convert mm_context_t to a struct # # include/asm-ppc64/mmu.h # 2004/03/06 23:05:29-08:00 akpm@osdl.org +14 -4 # ppc64: Convert mm_context_t to a struct # # arch/ppc64/mm/tlb.c # 2004/03/06 23:05:29-08:00 akpm@osdl.org +1 -1 # ppc64: Convert mm_context_t to a struct # # arch/ppc64/mm/init.c # 2004/03/06 23:05:29-08:00 akpm@osdl.org +1 -1 # ppc64: Convert mm_context_t to a struct # # arch/ppc64/mm/hugetlbpage.c # 2004/03/06 23:05:29-08:00 akpm@osdl.org +3 -4 # ppc64: Convert mm_context_t to a struct # # arch/ppc64/mm/hash_utils.c # 2004/03/06 23:05:29-08:00 akpm@osdl.org +1 -1 # ppc64: Convert mm_context_t to a struct # # arch/ppc64/kernel/stab.c # 2004/03/06 23:05:29-08:00 akpm@osdl.org +10 -10 # ppc64: Convert mm_context_t to a struct # # ChangeSet # 2004/03/07 00:48:42-08:00 akpm@osdl.org # [PATCH] ppc64: iSeries virtual cdrom driver # # From: Stephen Rothwell # # This patch adds the virtual cdrom driver for PPC64 iSeries. # # drivers/cdrom/viocd.c # 2004/03/06 23:05:28-08:00 akpm@osdl.org +656 -0 # ppc64: iSeries virtual cdrom driver # # drivers/cdrom/Makefile # 2004/03/06 23:05:28-08:00 akpm@osdl.org +1 -0 # ppc64: iSeries virtual cdrom driver # # arch/ppc64/Kconfig # 2004/03/06 23:05:28-08:00 akpm@osdl.org +0 -4 # ppc64: iSeries virtual cdrom driver # # drivers/cdrom/viocd.c # 2004/03/06 23:05:28-08:00 akpm@osdl.org +0 -0 # BitKeeper file /home/torvalds/v2.5/linux/drivers/cdrom/viocd.c # # ChangeSet # 2004/03/07 00:48:32-08:00 akpm@osdl.org # [PATCH] ppc64: iSeries_vio_dev cleanup # # From: Stephen Rothwell # # This patch declares iSeries_vio_dev in an include file and includes it where # necessary. It also fixes arch/ppc64/kernel/mf.c to use the generic dma API # with iSeries_vio_dev. # # include/asm-ppc64/iSeries/vio.h # 2004/03/06 23:05:28-08:00 akpm@osdl.org +4 -0 # ppc64: iSeries_vio_dev cleanup # # arch/ppc64/kernel/viopath.c # 2004/03/06 23:05:28-08:00 akpm@osdl.org +0 -3 # ppc64: iSeries_vio_dev cleanup # # arch/ppc64/kernel/mf.c # 2004/03/06 23:05:28-08:00 akpm@osdl.org +14 -13 # ppc64: iSeries_vio_dev cleanup # # arch/ppc64/kernel/iSeries_iommu.c # 2004/03/06 23:05:28-08:00 akpm@osdl.org +1 -5 # ppc64: iSeries_vio_dev cleanup # # ChangeSet # 2004/03/07 00:48:23-08:00 akpm@osdl.org # [PATCH] ppc64: Make xmon survive exit after soft reset # # From: Olof Johansson # # Below patch makes xmon survive a softreset invokation (and quite likely # invocations because of other traps as well). # # arch/ppc64/xmon/xmon.c # 2004/03/06 23:05:27-08:00 akpm@osdl.org +1 -1 # ppc64: Make xmon survive exit after soft reset # # ChangeSet # 2004/03/07 00:48:11-08:00 akpm@osdl.org # [PATCH] fastcall / regparm fixes # # From: Gerd Knorr # # Current gcc's error out if a function's declaration and definition disagree # about the register passing convention. # # The patch adds a new `fastcall' declatation primitive, and uses that in all # the FASTCALL functions which we could find. A number of inconsistencies were # fixed up along the way. # # net/bluetooth/rfcomm/core.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +2 -2 # fastcall / regparm fixes # # mm/swap.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +5 -5 # fastcall / regparm fixes # # mm/slab.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # mm/rmap.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +5 -5 # fastcall / regparm fixes # # mm/page_alloc.c # 2004/03/06 23:14:45-08:00 akpm@osdl.org +8 -8 # fastcall / regparm fixes # # mm/memory.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +3 -3 # fastcall / regparm fixes # # mm/highmem.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +2 -2 # fastcall / regparm fixes # # mm/filemap.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # lib/rwsem.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # lib/rwsem-spinlock.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +8 -8 # fastcall / regparm fixes # # kernel/workqueue.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +5 -5 # fastcall / regparm fixes # # kernel/timer.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # kernel/softirq.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # kernel/signal.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # kernel/sched.c # 2004/03/06 23:05:01-08:00 akpm@osdl.org +16 -15 # fastcall / regparm fixes # # kernel/rcupdate.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # kernel/pid.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +5 -5 # fastcall / regparm fixes # # kernel/fork.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +7 -7 # fastcall / regparm fixes # # kernel/exit.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +2 -2 # fastcall / regparm fixes # # include/linux/smp.h # 2004/03/06 23:05:01-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # include/linux/sched.h # 2004/03/06 23:05:01-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # include/linux/linkage.h # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -0 # fastcall / regparm fixes # # include/asm-um/linkage.h # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -0 # fastcall / regparm fixes # # include/asm-i386/smp.h # 2004/03/06 23:05:01-08:00 akpm@osdl.org +0 -1 # fastcall / regparm fixes # # include/asm-i386/linkage.h # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -0 # fastcall / regparm fixes # # fs/open.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +2 -2 # fastcall / regparm fixes # # fs/namei.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # fs/file_table.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # fs/fcntl.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # fs/buffer.c # 2004/03/06 23:30:56-08:00 akpm@osdl.org +2 -2 # fastcall / regparm fixes # # fs/aio.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +8 -8 # fastcall / regparm fixes # # drivers/net/ns83820.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +4 -4 # fastcall / regparm fixes # # arch/i386/kernel/vm86.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # arch/i386/kernel/smp.c # 2004/03/06 23:05:01-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # arch/i386/kernel/signal.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # arch/i386/kernel/process.c # 2004/03/06 23:04:57-08:00 akpm@osdl.org +1 -1 # fastcall / regparm fixes # # ChangeSet # 2004/03/07 00:47:59-08:00 akpm@osdl.org # [PATCH] drivers/sbus/char/vfc_dev.c needs mm.h # # From: Jakub Bogusz # # drivers/sbus/char/vfc_dev.c: In function `vfc_mmap': # drivers/sbus/char/vfc_dev.c:623: error: dereferencing pointer to incomplete type # # drivers/sbus/char/vfc_dev.c # 2004/03/06 23:04:56-08:00 akpm@osdl.org +1 -0 # drivers/sbus/char/vfc_dev.c needs mm.h # # ChangeSet # 2004/03/07 00:47:49-08:00 akpm@osdl.org # [PATCH] dm: remove v1 ioctl interface # # From: Joe Thornber # # Remove the version-1 ioctl interface. # # include/linux/dm-ioctl.h # 2004/03/06 23:04:56-08:00 akpm@osdl.org +229 -10 # dm: remove v1 ioctl interface # # include/linux/compat_ioctl.h # 2004/03/06 23:04:56-08:00 akpm@osdl.org +0 -14 # dm: remove v1 ioctl interface # # drivers/md/dm-ioctl.c # 2004/03/06 23:04:56-08:00 akpm@osdl.org +1257 -6 # dm: remove v1 ioctl interface # # drivers/md/Kconfig # 2004/03/06 23:04:56-08:00 akpm@osdl.org +0 -8 # dm: remove v1 ioctl interface # # arch/sparc64/kernel/ioctl32.c # 2004/03/06 23:04:56-08:00 akpm@osdl.org +0 -28 # dm: remove v1 ioctl interface # # arch/mips/kernel/ioctl32.c # 2004/03/06 23:04:56-08:00 akpm@osdl.org +0 -14 # dm: remove v1 ioctl interface # # BitKeeper/deleted/.del-dm-ioctl-v4.h~dc8692ec5a53ae8f # 2004/03/07 00:47:44-08:00 akpm@osdl.org +0 -0 # Delete: include/linux/dm-ioctl-v4.h # # BitKeeper/deleted/.del-dm-ioctl-v4.c~934f6abcc9ce02fa # 2004/03/07 00:47:44-08:00 akpm@osdl.org +0 -0 # Delete: drivers/md/dm-ioctl-v4.c # # BitKeeper/deleted/.del-dm-ioctl-v1.h~ab25145e1225660e # 2004/03/07 00:47:44-08:00 akpm@osdl.org +0 -0 # Delete: include/linux/dm-ioctl-v1.h # # BitKeeper/deleted/.del-dm-ioctl-v1.c~de661231f91d2eef # 2004/03/07 00:47:44-08:00 akpm@osdl.org +0 -0 # Delete: drivers/md/dm-ioctl-v1.c # # ChangeSet # 2004/03/07 00:47:39-08:00 akpm@osdl.org # [PATCH] svcauth_gss oops fix # # From: "J. Bruce Fields" # # I've done some testing with 2.6.4-rc1. It looks fine, except that one # critical patch got dropped somewhere along the way, without which # rpcsec_gss will oops. # # We've changed gss_get_mic to write mic in place instead of kmalloc'ing new # memory for it; change must also be reflected in server side code. # # net/sunrpc/auth_gss/svcauth_gss.c # 2004/03/06 23:04:55-08:00 akpm@osdl.org +4 -3 # svcauth_gss oops fix # # ChangeSet # 2004/03/06 16:11:47-08:00 trond.myklebust@fys.uio.no # [PATCH] Fix knfsd filehandles... # # Here's a fix for an obvious typo in changeset # neilb@cse.unsw.edu.au|ChangeSet|20040305155724|31191 # that was causing ESTALE errors galore on my NFS testrig. # # fs/nfsd/nfsfh.c # 2004/03/06 13:46:05-08:00 trond.myklebust@fys.uio.no +1 -0 # Fix knfsd filehandles... # # ChangeSet # 2004/03/06 09:40:18-08:00 zippel@linux-m68k.org # [PATCH] hfsplus: symlink initialization fix # # This fixes a problem with creating symlinks, a few fields in the # inode/dentry were left uninitialized. # # fs/hfsplus/inode.c # 2004/03/04 07:55:25-08:00 zippel@linux-m68k.org +8 -8 # hfsplus: symlink initialization fix # # fs/hfsplus/dir.c # 2004/03/04 07:49:30-08:00 zippel@linux-m68k.org +2 -0 # hfsplus: symlink initialization fix # # ChangeSet # 2004/03/06 08:19:13-08:00 torvalds@ppc970.osdl.org # Merge bk://linux-acpi.bkbits.net/linux-acpi-release-2.6.4 # into ppc970.osdl.org:/home/torvalds/v2.5/linux # # MAINTAINERS # 2004/03/06 08:19:10-08:00 torvalds@ppc970.osdl.org +0 -0 # Auto merged # # arch/ppc/kernel/head.S # 2004/03/06 03:03:00-08:00 benh@kernel.crashing.org +16 -16 # High BAT initialization wrong # # ChangeSet # 2004/03/06 14:47:10+11:00 nathans@sgi.com # [XFS] Fix out-of-space deadlock when flushing delalloc data with pages locked under write. # # SGI Modid: xfs-linux:xfs-kern:167948a # # fs/xfs/linux/xfs_super.c # 2004/03/06 14:46:51+11:00 nathans@sgi.com +1 -1 # [XFS] Fix out-of-space deadlock when flushing delalloc data with pages locked under write. # # ChangeSet # 2004/03/06 14:21:39+11:00 sandeen@sgi.com # [XFS] zero log buffer during initialization at mount time # # SGI Modid: xfs-linux:xfs-kern:167980a # # fs/xfs/xfs_log.c # 2004/03/06 14:16:30+11:00 sandeen@sgi.com +1 -1 # [XFS] zero log buffer during initialization at mount time # # ChangeSet # 2004/03/05 18:11:56-08:00 akpm@osdl.org # [PATCH] Add missing AFAVLAB P030 PCI ID # # include/linux/pci_ids.h # 2004/03/05 09:51:03-08:00 akpm@osdl.org +1 -0 # Add missing AFAVLAB P030 PCI ID # # ChangeSet # 2004/03/05 16:16:20-08:00 benh@kernel.crashing.org # [PATCH] High BAT initialization wrong # # The code initializing the "high" BATs on CPUs like the 750FX got # broken when copied over from 2.4. This cause random problems with # machines using those CPUs (iBook 2s typically). # # ChangeSet # 2004/03/05 15:19:34-08:00 davej@redhat.com # [PATCH] mismatched syscall protos. # # Sparse noticed a bunch of mismatched prototypes in the new syscalls.h file # when compiling net/socket.c Whilst most of them are just missing __user # tags, the last argument of sys_socketpair was completely different. # # include/linux/syscalls.h # 2004/03/05 09:55:40-08:00 davej@redhat.com +13 -13 # mismatched syscall protos. # # ChangeSet # 2004/03/05 14:20:35-08:00 dlstevens@us.ibm.com # [IPV4]: Add sysctl for per-socket limit on number of mcast src filters. # # net/ipv4/sysctl_net_ipv4.c # 2004/03/05 14:17:31-08:00 dlstevens@us.ibm.com +9 -0 # [IPV4]: Add sysctl for per-socket limit on number of mcast src filters. # # net/ipv4/ip_sockglue.c # 2004/03/05 14:17:31-08:00 dlstevens@us.ibm.com +9 -3 # [IPV4]: Add sysctl for per-socket limit on number of mcast src filters. # # net/ipv4/igmp.c # 2004/03/05 14:17:31-08:00 dlstevens@us.ibm.com +7 -1 # [IPV4]: Add sysctl for per-socket limit on number of mcast src filters. # # include/linux/sysctl.h # 2004/03/05 14:17:31-08:00 dlstevens@us.ibm.com +1 -0 # [IPV4]: Add sysctl for per-socket limit on number of mcast src filters. # # ChangeSet # 2004/03/05 14:15:11-08:00 i.palsenberg@jdirmedia.nl # [QLOGIC]: Mark mbox_param[] as static to avoid namespace pollution. # # drivers/scsi/qlogicpti.c # 2004/03/05 14:12:06-08:00 i.palsenberg@jdirmedia.nl +1 -1 # [QLOGIC]: Mark mbox_param[] as static to avoid namespace pollution. # # drivers/scsi/qlogicfc.c # 2004/03/05 14:12:06-08:00 i.palsenberg@jdirmedia.nl +1 -1 # [QLOGIC]: Mark mbox_param[] as static to avoid namespace pollution. # # ChangeSet # 2004/03/05 14:06:40-08:00 davem@nuts.davemloft.net # Merge http://linux-mh.bkbits.net/bluetooth-2.6 # into nuts.davemloft.net:/disk1/BK/net-2.6 # # net/bluetooth/rfcomm/core.c # 2004/03/05 14:06:33-08:00 davem@nuts.davemloft.net +0 -0 # Auto merged # # ChangeSet # 2004/03/05 21:35:39+00:00 rmk@flint.arm.linux.org.uk # [SERIAL] Correct Oxford Semiconductor 16PCI952 PCI type entry. # # WRT 2.4, Ed Vance put this fix into 2.4: # # According to the data sheet, the OX16PCI952 has port 0 in BAR0 and # port 1 in BAR1. (unlike the OX16C954, BTW) The 921600 base baud value # is your oscillator rate divided by the default oversample rate, 16. # # Since 2.6 PCI IDs have been updated to use the real device ID for # this part, we really should include this fix as well. # # drivers/serial/8250_pci.c # 2004/03/05 21:33:45+00:00 rmk@flint.arm.linux.org.uk +1 -1 # [PATCH] Correct Oxford Semiconductor 16PCI952 PCI type entry. # # ChangeSet # 2004/03/05 21:12:13+00:00 rmk@flint.arm.linux.org.uk # [SERIAL] Don't initialise port->mctrl before calling ->startup # # If a serial port is hung up using vhangup() with HUPCL cleared (so # DTR isn't dropped), and then re-opened, we don't want to drop the # DTR line. This occurs during the login process, and dropping DTR # would cause a modem to hang up. # # drivers/serial/serial_core.c # 2004/03/05 21:10:35+00:00 rmk@flint.arm.linux.org.uk +0 -2 # Don't initialise port->mctrl to zero before calling ->startup. # # ChangeSet # 2004/03/05 21:02:55+00:00 rmk@flint.arm.linux.org.uk # [SERIAL] Clear up comments concerning mapbase and membase. # # drivers/serial/8250.c # 2004/03/05 21:01:10+00:00 rmk@flint.arm.linux.org.uk +2 -6 # Clear up comments concerning mapbase and membase. # # ChangeSet # 2004/03/05 20:50:33+00:00 rmk@flint.arm.linux.org.uk # [SERIAL] Remove obsolete CLPS711x serial driver names. # # drivers/serial/clps711x.c # 2004/03/05 20:48:28+00:00 rmk@flint.arm.linux.org.uk +0 -9 # Remove old CLPS711x serial driver namespace. # # drivers/serial/Kconfig # 2004/03/05 20:48:28+00:00 rmk@flint.arm.linux.org.uk +0 -6 # Remove SERIAL_CLPS711X_OLD_NAME. # # ChangeSet # 2004/03/05 20:41:31+00:00 laforge@org.rmk.(none) # [SERIAL] Fix supprot for AFAVLAB 8port boards in 2.6.x # # I didn't yet use one of my AFAVLAB boards with 2.6.x until now. The # upper 4 ports are not detected at all. I suppose the bug was # introduced while porting the driver from 2.4.x. # # Please consider applying the following patch. It also adds support # for a new 8 port board called P030. # # drivers/serial/8250_pci.c # 2004/03/05 20:39:21+00:00 laforge@org.rmk.(none) +6 -1 # [PATCH] Fix supprot for AFAVLAB 8port boards in 2.6.x # # drivers/pci/pci.ids # 2004/03/05 20:39:20+00:00 laforge@org.rmk.(none) +2 -0 # [PATCH] Fix supprot for AFAVLAB 8port boards in 2.6.x # # ChangeSet # 2004/03/05 20:16:43+00:00 bjorn.helgaas@com.rmk.(none) # [SERIAL] Make serial console work for any port (take 2) # # The current serial console code only works for ports that are either # defined in SERIAL_PORT_DFNS (and set up by serial8250_isa_init_ports()) # or registered by early_serial_setup(). # # On ia64, SERIAL_PORT_DFNS is empty because we discover everything # via ACPI and PCI. And we only use early_serial_setup() for one port # described by the HCDP firmware table. # # This patch against 2.6.4-rc1 makes it work for any valid port. If we # don't know about the port early, we just return -ENODEV from the # setup() function, which leaves the serial console disabled. After the # driver has found all the ports, we try to register the serial console # again if it hasn't been enabled already. # # Keith Owens noticed that the first version of this patch broke some # serial console setups because many early serial ports are registered # with "type == PORT_UNKNOWN". So this version tests "port->ops" # instead, and Keith has confirmed that this works for him. # # drivers/serial/serial_core.c # 2004/03/05 20:14:38+00:00 bjorn.helgaas@com.rmk.(none) +0 -3 # [PATCH] Make serial console work for any port (take 2) # # drivers/serial/8250.c # 2004/03/05 20:14:38+00:00 bjorn.helgaas@com.rmk.(none) +10 -0 # [PATCH] Make serial console work for any port (take 2) # # ChangeSet # 2004/03/05 18:53:50+01:00 marcel@holtmann.org # [Bluetooth] Dynamic allocation of the RFCOMM TTY devices # # Only allocate the RFCOMM TTY devices when they are really in use. This # prevents the system from calling hotplug and udev 256 times to create or # remove every device node. In fact this makes the loading and unloading # of the RFCOMM module much faster. # # net/bluetooth/rfcomm/tty.c # 2004/03/05 18:49:31+01:00 marcel@holtmann.org +10 -5 # Dynamic allocation of the RFCOMM TTY devices # # net/bluetooth/rfcomm/core.c # 2004/03/05 18:49:29+01:00 marcel@holtmann.org +1 -1 # Dynamic allocation of the RFCOMM TTY devices # # ChangeSet # 2004/03/05 17:43:26+01:00 marcel@holtmann.org # [Bluetooth] Add notify callback for host drivers # # This patch adds a notification callback to the hci_dev structure which # is used by the HCI core to tell the driver about connection creation # and clearing. It also notifies about changed voice setting. # # net/bluetooth/hci_event.c # 2004/03/05 17:42:45+01:00 marcel@holtmann.org +6 -0 # Add notify callback for host drivers # # net/bluetooth/hci_conn.c # 2004/03/05 17:42:43+01:00 marcel@holtmann.org +6 -0 # Add notify callback for host drivers # # include/net/bluetooth/hci_core.h # 2004/03/05 17:42:40+01:00 marcel@holtmann.org +1 -0 # Add notify callback for host drivers # # include/net/bluetooth/hci.h # 2004/03/05 17:42:28+01:00 marcel@holtmann.org +23 -18 # Add notify callback for host drivers # # ChangeSet # 2004/03/05 17:27:52+01:00 marcel@holtmann.org # [Bluetooth] Send HCI_Reset for some Broadcom dongles # # This patch introduces a quirk flag for sending the HCI_Reset command. In # general the HCI_Reset is not needed, but some Broadcom dongles uses this # reset command to switch from HID to HCI mode. And it is not safe to send # the HCI_Reset to every Bluetooth device, because the CSR firmware prior # HCI 12.x will reset the host transport and this is wrong according to the # Bluetooth specification. # # net/bluetooth/hci_core.c # 2004/03/05 17:18:05+01:00 marcel@holtmann.org +4 -0 # Send HCI_Reset for some Broadcom dongles # # include/net/bluetooth/hci_core.h # 2004/03/05 17:18:05+01:00 marcel@holtmann.org +2 -0 # Send HCI_Reset for some Broadcom dongles # # include/net/bluetooth/hci.h # 2004/03/05 17:18:05+01:00 marcel@holtmann.org +5 -0 # Send HCI_Reset for some Broadcom dongles # # drivers/bluetooth/hci_usb.h # 2004/03/05 17:18:04+01:00 marcel@holtmann.org +2 -1 # Send HCI_Reset for some Broadcom dongles # # drivers/bluetooth/hci_usb.c # 2004/03/05 17:18:03+01:00 marcel@holtmann.org +26 -9 # Send HCI_Reset for some Broadcom dongles # # ChangeSet # 2004/03/05 07:57:24-08:00 neilb@cse.unsw.edu.au # [PATCH] kNFSd - Tidy up new filehandle type. # # nfsd uses several different mechanisms for identifying the filesystem # from the filehandle. # # This patch: # Marks type 2 as deprecated - it wastes space, and space in the filehandle # is not unlimited # Adds type 3 which handles new, large device number in 32bits of space # Tidies up the code for determining which type to use in a newly created # filehandle - the addition of type 2 broke this code. # # include/linux/nfsd/nfsfh.h # 2004/03/04 21:36:13-08:00 neilb@cse.unsw.edu.au +20 -1 # kNFSd - Tidy up new filehandle type. # # fs/nfsd/nfsfh.c # 2004/03/04 21:36:13-08:00 neilb@cse.unsw.edu.au +47 -33 # kNFSd - Tidy up new filehandle type. # # fs/nfsd/export.c # 2004/03/04 21:36:13-08:00 neilb@cse.unsw.edu.au +4 -9 # kNFSd - Tidy up new filehandle type. # # drivers/video/aty/radeon_base.c # 2004/03/05 02:40:50-08:00 benh@kernel.crashing.org +1 -1 # Fix typo in radeonfb # # ChangeSet # 2004/03/04 23:05:03-08:00 bgerst@didntduck.org # [PATCH] PnP BIOS exception fixes # # This fixes two errors in fixup_exception() for PnP BIOS faults: # - Check for the correct segments used for the BIOS # - Fix asm constraints so that EIP and ESP are properly reloaded # # arch/i386/mm/extable.c # 2004/03/04 07:45:33-08:00 bgerst@didntduck.org +2 -2 # PnP BIOS exception fixes # # ChangeSet # 2004/03/04 22:00:48-08:00 wesolows@foobazco.org # [SPARC]: Make parport_sunbpp compile again # # drivers/parport/parport_sunbpp.c # 2004/03/04 22:00:42-08:00 wesolows@foobazco.org +3 -2 # [SPARC]: Make parport_sunbpp compile again # # ChangeSet # 2004/03/04 21:57:18-08:00 wesolows@foobazco.org # [SPARC]: Add stack usage instrumentation # # include/asm-sparc/thread_info.h # 2004/03/04 21:57:03-08:00 wesolows@foobazco.org +2 -2 # [SPARC]: Add stack usage instrumentation # # arch/sparc/mm/sun4c.c # 2004/03/04 21:57:03-08:00 wesolows@foobazco.org +5 -0 # [SPARC]: Add stack usage instrumentation # # arch/sparc/mm/srmmu.c # 2004/03/04 21:57:03-08:00 wesolows@foobazco.org +9 -2 # [SPARC]: Add stack usage instrumentation # # arch/sparc/Kconfig # 2004/03/04 21:57:03-08:00 wesolows@foobazco.org +31 -2 # [SPARC]: Add stack usage instrumentation # # ChangeSet # 2004/03/04 20:31:35-08:00 akpm@osdl.org # [PATCH] another rd.c leak # # Free the request queues on the rd_init() error recovery path. # # drivers/block/rd.c # 2004/03/04 19:10:29-08:00 akpm@osdl.org +3 -1 # another rd.c leak # # ChangeSet # 2004/03/04 21:48:44-05:00 jgarzik@redhat.com # Fix ramdisk driver leak on module unload. # # Noticed by me, fixed by Jens. # # drivers/block/rd.c # 2004/03/04 21:47:24-05:00 jgarzik@redhat.com +1 -0 # Fix ramdisk driver leak on module unload. # # Noticed by me, fixed by Jens. # # ChangeSet # 2004/03/04 18:22:43-08:00 davem@nuts.davemloft.net # [FFB]: Force-disable cursor in ffb_switch_from_graph(). # # drivers/video/ffb.c # 2004/03/04 18:22:25-08:00 davem@nuts.davemloft.net +9 -0 # [FFB]: Force-disable cursor in ffb_switch_from_graph(). # # ChangeSet # 2004/03/04 15:57:35-08:00 benh@kernel.crashing.org # [PATCH] Fix typo in radeonfb # # This fixes a typo in the list of PCI IDs in radeonfb, which in turn # fixes detection of some mobility models. # # ChangeSet # 2004/03/04 22:17:06+00:00 dsaxena@net.rmk.(none) # [ARM PATCH] 1757/1: Allow building of LE kernels with BE-default toolchain # # Patch from Deepak Saxena # # The ARM makefile currently assumes that the compiler being used # defaults to little-endian builds unless the big-endian options # are provided. This may not always be the case (my toolchains default # to BE since that's what I mostly work with) so this patch forces # endianess options to be passed to the toolchain. W/O this, # building without CONFIG_CPU_BIG_ENDIAN on a big-endian toolchain # will still result in a big-endian kernel. # # arch/arm/Makefile # 2004/02/19 10:47:57+00:00 dsaxena@net.rmk.(none) +5 -0 # [PATCH] 1757/1: Allow building of LE kernels with BE-default toolchain # # ChangeSet # 2004/03/04 22:13:54+00:00 icampbell@com.rmk.(none) # [ARM PATCH] 1764/1: Export __arch_strncpy_from_user for modules # # Patch from Ian Campbell # # __arch_strncpy_from_user needs to be exported if you build the # framebuffer console driver as a module. # # arch/arm/kernel/armksyms.c # 2004/02/27 14:55:02+00:00 icampbell@com.rmk.(none) +1 -0 # [PATCH] 1764/1: Export __arch_strncpy_from_user for modules # # ChangeSet # 2004/03/04 22:13:37+00:00 dsaxena@net.rmk.(none) # [ARM PATCH] 1762/1: Fix typo in CONFIG_CPU_BIG_ENDIAN help text # # Patch from Deepak Saxena # # # arch/arm/mm/Kconfig # 2004/02/20 23:32:19+00:00 dsaxena@net.rmk.(none) +1 -1 # [PATCH] 1762/1: Fix typo in CONFIG_CPU_BIG_ENDIAN help text # # ChangeSet # 2004/03/04 13:23:44-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: hpfs # # - inode leak on d_alloc_root() failure # # fs/hpfs/super.c # 2004/03/04 07:27:34-08:00 viro@www.linux.org.uk +21 -17 # d_alloc_root() fixes: hpfs # # ChangeSet # 2004/03/04 13:23:34-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: romfs # # - inode leak on d_alloc_root() failure # - sanitized the cleanup logics # # fs/romfs/inode.c # 2004/03/04 07:17:15-08:00 viro@www.linux.org.uk +13 -10 # d_alloc_root() fixes: romfs # # ChangeSet # 2004/03/04 13:23:25-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: hfsplus # # - inode leak on d_alloc_root() failure # # fs/hfsplus/super.c # 2004/03/04 07:15:12-08:00 viro@www.linux.org.uk +4 -1 # d_alloc_root() fixes: hfsplus # # ChangeSet # 2004/03/04 13:23:16-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: hfs # # - inode leak on d_alloc_root() failure # # fs/hfs/super.c # 2004/03/04 07:14:05-08:00 viro@www.linux.org.uk +3 -1 # d_alloc_root() fixes: hfs # # ChangeSet # 2004/03/04 13:23:06-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: freevxfs # # - inode leak on d_alloc_root() failure # # fs/freevxfs/vxfs_super.c # 2004/03/04 07:11:53-08:00 viro@www.linux.org.uk +4 -1 # d_alloc_root() fixes: freevxfs # # ChangeSet # 2004/03/04 13:22:57-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: ext3 # # - inode leak on d_alloc_root() failure # # fs/ext3/super.c # 2004/03/04 07:10:40-08:00 viro@www.linux.org.uk +12 -10 # d_alloc_root() fixes: ext3 # # ChangeSet # 2004/03/04 13:22:48-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: ext2 # # - inode leak on d_alloc_root() failure # # fs/ext2/super.c # 2004/03/04 07:09:26-08:00 viro@www.linux.org.uk +12 -9 # d_alloc_root() fixes: ext2 # # ChangeSet # 2004/03/04 13:22:39-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: efs # # - inode leak on d_alloc_root() failure # # fs/efs/super.c # 2004/03/04 07:08:04-08:00 viro@www.linux.org.uk +4 -1 # d_alloc_root() fixes: efs # # ChangeSet # 2004/03/04 13:22:29-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: cramfs # # - inode leak on d_alloc_root() failure # - unchecked result of d_alloc_root() leading to oops in fs/super.c # # fs/cramfs/inode.c # 2004/03/04 07:06:24-08:00 viro@www.linux.org.uk +9 -1 # d_alloc_root() fixes: cramfs # # ChangeSet # 2004/03/04 13:22:20-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: coda # # - unchecked result of d_alloc_root() leading to oops in fs/super.c # # fs/coda/inode.c # 2004/03/04 07:04:52-08:00 viro@www.linux.org.uk +2 -0 # d_alloc_root() fixes: coda # # ChangeSet # 2004/03/04 13:22:11-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: befs # # - inode leak if d_alloc_root() fails. # # fs/befs/linuxvfs.c # 2004/03/04 07:03:10-08:00 viro@www.linux.org.uk +4 -2 # d_alloc_root() fixes: befs # # ChangeSet # 2004/03/04 13:22:02-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: autofs4 # # - oops if inode allocation fails. # # fs/autofs4/inode.c # 2004/03/04 07:00:16-08:00 viro@www.linux.org.uk +3 -9 # d_alloc_root() fixes: autofs4 # # ChangeSet # 2004/03/04 13:21:52-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: afs # # - useless dput(NULL) on failure exit (would be a double-free if # we ever got there with non-NULL dentry). # # fs/afs/super.c # 2004/03/04 06:58:24-08:00 viro@www.linux.org.uk +0 -1 # d_alloc_root() fixes: afs # # ChangeSet # 2004/03/04 13:21:43-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: adfs # # - leak of root inode if d_alloc_root() fails. # # fs/adfs/super.c # 2004/03/04 06:57:00-08:00 viro@www.linux.org.uk +4 -2 # d_alloc_root() fixes: adfs # # ChangeSet # 2004/03/04 13:21:34-08:00 viro@www.linux.org.uk # [PATCH] d_alloc_root() fixes: gadgetfs # # gatgetfs fill_super: # - double-free of inode on last two failure exits # - leak on the last failure exit # - touching addresses near 0 on last two failure exits # # drivers/usb/gadget/inode.c # 2004/03/04 07:46:30-08:00 viro@www.linux.org.uk +10 -6 # d_alloc_root() fixes: gadgetfs # # ChangeSet # 2004/03/04 13:07:54-08:00 davem@nuts.davemloft.net # [SPARC64]: Update defconfig. # # arch/sparc64/defconfig # 2004/03/04 13:05:04-08:00 davem@nuts.davemloft.net +2 -0 # [SPARC64]: Update defconfig. # # ChangeSet # 2004/03/04 00:15:04-08:00 jon@focalhost.com # [CRYPTO]: Add ARC4 module. # # crypto/tcrypt.h # 2004/03/04 00:14:43-08:00 jon@focalhost.com +141 -0 # [CRYPTO]: Add ARC4 module. # # crypto/tcrypt.c # 2004/03/04 00:14:43-08:00 jon@focalhost.com +10 -1 # [CRYPTO]: Add ARC4 module. # # crypto/Makefile # 2004/03/04 00:14:43-08:00 jon@focalhost.com +1 -0 # [CRYPTO]: Add ARC4 module. # # crypto/Kconfig # 2004/03/04 00:14:43-08:00 jon@focalhost.com +10 -0 # [CRYPTO]: Add ARC4 module. # # Documentation/crypto/api-intro.txt # 2004/03/04 00:14:43-08:00 jon@focalhost.com +1 -0 # [CRYPTO]: Add ARC4 module. # # crypto/arc4.c # 2004/03/04 00:14:38-08:00 jon@focalhost.com +106 -0 # [CRYPTO]: Add ARC4 module. # # crypto/arc4.c # 2004/03/04 00:14:38-08:00 jon@focalhost.com +0 -0 # BitKeeper file /disk1/BK/net-2.6/crypto/arc4.c # # ChangeSet # 2004/03/04 00:13:04-08:00 shemminger@osdl.org # [IRDA]: stir4200 update for 2.6.4-rc1 # # New revision of the Sigmatel irda driver. This version has much # better performance and doesn't drop frames in FIR mode. # Tested with both UHCI and EHCI/OHCI against nsc-ircc on laptop. # Thanks to Martin for additional testing and feedback. # # * Receiver: # - changed from interrupt to bulk URB. Queue's one bulk # urb per USB tick (1ms). # - FIR unpack now uses get_unaligned and cpu32_le # instead of explicit shifts # - FIR unpack copies small frames # * Transmitter: # - pack data into io buffer. Since irda is half duplex # can use same buffer for transmit and receive. # - use xchange and wait_event for synchronization # * Other: # - use USB format messages rather than IRDA (ugly) # - clean up USB startup # - reset device on network open to clear up stuck state # - handle FIFO errors # - disconnect cleanup (from viro) # - don't DMA onto stack when reading fifo status # # drivers/net/irda/stir4200.c # 2004/03/04 00:08:24-08:00 shemminger@osdl.org +266 -362 # [IRDA]: stir4200 update for 2.6.4-rc1 # # New revision of the Sigmatel irda driver. This version has much # better performance and doesn't drop frames in FIR mode. # Tested with both UHCI and EHCI/OHCI against nsc-ircc on laptop. # Thanks to Martin for additional testing and feedback. # # * Receiver: # - changed from interrupt to bulk URB. Queue's one bulk # urb per USB tick (1ms). # - FIR unpack now uses get_unaligned and cpu32_le # instead of explicit shifts # - FIR unpack copies small frames # * Transmitter: # - pack data into io buffer. Since irda is half duplex # can use same buffer for transmit and receive. # - use xchange and wait_event for synchronization # * Other: # - use USB format messages rather than IRDA (ugly) # - clean up USB startup # - reset device on network open to clear up stuck state # - handle FIFO errors # - disconnect cleanup (from viro) # - don't DMA onto stack when reading fifo status # # ChangeSet # 2004/03/03 10:28:27-08:00 davem@nuts.davemloft.net # [SPARC64]: Update defconfig. # # arch/sparc64/defconfig # 2004/03/03 10:25:23-08:00 davem@nuts.davemloft.net +10 -3 # [SPARC64]: Update defconfig. # # ChangeSet # 2004/03/02 19:40:14-08:00 davem@nuts.davemloft.net # [SPARC]: Kill sys_ioperm decl from unistd.h # # include/asm-sparc/unistd.h # 2004/03/02 19:37:09-08:00 davem@nuts.davemloft.net +0 -1 # [SPARC]: Kill sys_ioperm decl from unistd.h # # ChangeSet # 2004/03/01 03:30:57-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.3 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # # arch/i386/kernel/acpi/boot.c # 2004/03/01 03:30:55-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/03/01 03:27:14-05:00 len.brown@intel.com # [ACPI] delete ACPI table parsing code from bootflags module # # include/linux/acpi.h # 2004/03/01 03:26:35-05:00 len.brown@intel.com +22 -1 # [ACPI] delete ACPI table parsing code from bootflags module # # arch/i386/kernel/bootflag.c # 2004/03/01 03:26:35-05:00 len.brown@intel.com +8 -162 # [ACPI] delete ACPI table parsing code from bootflags module # # arch/i386/kernel/acpi/boot.c # 2004/03/01 03:26:35-05:00 len.brown@intel.com +21 -0 # [ACPI] delete ACPI table parsing code from bootflags module # # ChangeSet # 2004/03/01 01:25:41-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.3 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # # arch/i386/kernel/acpi/boot.c # 2004/03/01 01:25:38-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/03/01 01:25:38-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/03/01 01:22:10-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.2 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.3 # # arch/i386/kernel/acpi/boot.c # 2004/03/01 01:22:07-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/Kconfig # 2004/03/01 01:22:07-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/03/01 01:20:58-05:00 len.brown@intel.com # [ACPI] Support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/pci/mmconfig.c # 2004/03/01 01:20:00-05:00 len.brown@intel.com +109 -0 # # include/linux/acpi.h # 2004/03/01 01:20:00-05:00 len.brown@intel.com +12 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # include/asm-i386/fixmap.h # 2004/03/01 01:20:00-05:00 len.brown@intel.com +3 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # drivers/acpi/tables.c # 2004/03/01 01:20:00-05:00 len.brown@intel.com +1 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/pci/pci.h # 2004/03/01 01:20:00-05:00 len.brown@intel.com +3 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/pci/mmconfig.c # 2004/03/01 01:20:00-05:00 len.brown@intel.com +0 -0 # BitKeeper file /home/lenb/src/linux-acpi-test-2.6.2/arch/i386/pci/mmconfig.c # # arch/i386/pci/common.c # 2004/03/01 01:20:00-05:00 len.brown@intel.com +8 -1 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/pci/Makefile # 2004/03/01 01:20:00-05:00 len.brown@intel.com +1 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/kernel/acpi/boot.c # 2004/03/01 01:20:00-05:00 len.brown@intel.com +31 -0 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # arch/i386/Kconfig # 2004/03/01 01:20:00-05:00 len.brown@intel.com +16 -6 # ACPI support for PCI MMCONFIG for PCI Express (Matt Wilcox) # # ChangeSet # 2004/03/01 00:38:45-05:00 len.brown@intel.com # merge # # arch/i386/kernel/acpi/boot.c # 2004/03/01 00:38:40-05:00 len.brown@intel.com +4 -0 # merge # # ChangeSet # 2004/03/01 00:07:00-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.2 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.3 # # arch/i386/kernel/acpi/boot.c # 2004/03/01 00:06:56-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/03/01 00:05:29-05:00 len.brown@intel.com # [ACPI] acpi_boot_init() cleanup suggested by Matt Wilcox # HPET doesn't depend on IOAPIC # # drivers/acpi/tables.c # 2004/03/01 00:04:48-05:00 len.brown@intel.com +8 -0 # comments # # arch/i386/kernel/acpi/boot.c # 2004/03/01 00:04:48-05:00 len.brown@intel.com +149 -119 # [ACPI] acpi_boot_init cleanup suggested by Matt Wilcox # HPET doesn't depend on IOAPIC # # ChangeSet # 2004/02/27 02:43:57-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.4 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.4 # # MAINTAINERS # 2004/02/27 02:43:54-05:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/02/27 02:43:54-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/02/27 02:02:53-05:00 len.brown@intel.com # Merge # # drivers/acpi/Kconfig # 2004/02/27 02:02:52-05:00 len.brown@intel.com +0 -0 # SCCS merged # # drivers/acpi/hardware/hwsleep.c # 2004/02/27 01:59:50-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/acpi/boot.c # 2004/02/27 01:59:50-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/02/27 01:59:50-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/02/27 01:59:50-05:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/02/27 01:59:50-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/02/27 01:53:19-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.2 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.3 # # include/asm-i386/acpi.h # 2004/02/27 01:53:16-05:00 len.brown@intel.com +0 -0 # Auto merged # # drivers/acpi/Kconfig # 2004/02/27 01:53:16-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/x86_64/kernel/acpi/boot.c # 2004/02/27 01:53:16-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/setup.c # 2004/02/27 01:53:16-05:00 len.brown@intel.com +0 -0 # Auto merged # # arch/i386/kernel/acpi/boot.c # 2004/02/27 01:53:16-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/02/27 01:49:56-05:00 len.brown@intel.com # Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.1 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.2 # # include/asm-ia64/acpi.h # 2004/02/27 01:49:53-05:00 len.brown@intel.com +0 -0 # Auto merged # # Documentation/kernel-parameters.txt # 2004/02/27 01:49:53-05:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/02/27 01:37:00-05:00 len.brown@intel.com # [ACPI] ACPICA 20040220 from Bob Moore # # Implemented execution of _SxD methods for Device objects in the # GetObjectInfo interface. # # Fixed calls to _SST method to pass the correct arguments. # # Added a call to _SST on wake to restore to "working" state. # # Check for End-Of-Buffer failure case in the WalkResources interface. # # Integrated fix for 64-bit alignment issue in acglobal.h by moving two # structures to the beginning of the file. # # After wake, clear GPE status register(s) before enabling GPEs. # # After wake, clear/enable power button. # (Perhaps we should clear/enable all fixed events upon wake.) # # Fixed a couple of possible memory leaks in the Namespace manager. # # include/acpi/acutils.h # 2004/02/26 20:20:52-05:00 len.brown@intel.com +4 -0 # Import patch acpica-unix-20040220.patch # # include/acpi/actypes.h # 2004/02/26 20:20:52-05:00 len.brown@intel.com +2 -1 # Import patch acpica-unix-20040220.patch # # include/acpi/acglobal.h # 2004/02/26 20:20:52-05:00 len.brown@intel.com +13 -12 # Import patch acpica-unix-20040220.patch # # include/acpi/acconfig.h # 2004/02/26 20:20:52-05:00 len.brown@intel.com +1 -1 # Import patch acpica-unix-20040220.patch # # drivers/acpi/utilities/utglobal.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +6 -1 # Import patch acpica-unix-20040220.patch # # drivers/acpi/utilities/uteval.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +60 -0 # Import patch acpica-unix-20040220.patch # # drivers/acpi/resources/rsxface.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +17 -1 # Import patch acpica-unix-20040220.patch # # drivers/acpi/namespace/nsxfname.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +7 -0 # Import patch acpica-unix-20040220.patch # # drivers/acpi/namespace/nsutils.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +3 -3 # Import patch acpica-unix-20040220.patch # # drivers/acpi/namespace/nseval.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +2 -2 # Import patch acpica-unix-20040220.patch # # drivers/acpi/hardware/hwsleep.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +59 -7 # Import patch acpica-unix-20040220.patch # # drivers/acpi/hardware/hwregs.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +3 -3 # Import patch acpica-unix-20040220.patch # # drivers/acpi/hardware/hwgpe.c # 2004/02/26 20:20:55-05:00 len.brown@intel.com +8 -0 # Import patch acpica-unix-20040220.patch # # ChangeSet # 2004/02/27 01:01:05-05:00 len.brown@intel.com # [ACPI] include CONFIG_ACPI_RELAXED_AML code always # add acpi=strict option to disable platform workarounds # # include/asm-ia64/acpi.h # 2004/02/27 00:59:39-05:00 len.brown@intel.com +2 -0 # add acpi=strict -- ignored on ia64 # # include/asm-x86_64/acpi.h # 2004/02/27 00:57:51-05:00 len.brown@intel.com +1 -0 # add acpi=strict # # include/asm-i386/acpi.h # 2004/02/27 00:57:51-05:00 len.brown@intel.com +1 -0 # add acpi=strict # # drivers/acpi/executer/exfldio.c # 2004/02/27 00:57:51-05:00 len.brown@intel.com +3 -4 # delete CONFIG_ACPI_RELAXED_AML option # it is now included always and controled by acpi=strict # # drivers/acpi/Kconfig # 2004/02/27 00:57:51-05:00 len.brown@intel.com +0 -12 # delete CONFIG_ACPI_RELAXED_AML option # it is now included always # # arch/x86_64/kernel/acpi/boot.c # 2004/02/27 00:57:51-05:00 len.brown@intel.com +2 -1 # add acpi=strict # # arch/i386/kernel/setup.c # 2004/02/27 00:57:50-05:00 len.brown@intel.com +5 -0 # add acpi=strict # # arch/i386/kernel/acpi/boot.c # 2004/02/27 00:57:50-05:00 len.brown@intel.com +2 -1 # add acpi=strict # # Documentation/kernel-parameters.txt # 2004/02/27 00:57:50-05:00 len.brown@intel.com +4 -1 # add acpi=strict # # ChangeSet # 2004/02/26 00:11:52-05:00 len.brown@intel.com # [ACPI] delete unnecessary dmesg lines, fix spelling # # drivers/acpi/pci_link.c # 2004/02/26 00:11:46-05:00 len.brown@intel.com +0 -2 # reduce dmesg verbosity # # arch/x86_64/kernel/mpparse.c # 2004/02/26 00:11:46-05:00 len.brown@intel.com +1 -1 # reduce dmesg verbosity # # arch/x86_64/kernel/acpi/boot.c # 2004/02/26 00:11:46-05:00 len.brown@intel.com +1 -1 # spelling # # arch/i386/kernel/mpparse.c # 2004/02/26 00:11:46-05:00 len.brown@intel.com +1 -1 # reduce dmesg verbosity # # arch/i386/kernel/acpi/boot.c # 2004/02/26 00:11:46-05:00 len.brown@intel.com +1 -1 # spelling # # ChangeSet # 2004/02/25 14:43:51-05:00 len.brown@intel.com # ACPI URL update # # MAINTAINERS # 2004/02/25 14:43:46-05:00 len.brown@intel.com +1 -1 # ACPI URL update # # ChangeSet # 2004/02/23 21:57:00-08:00 wesolows@foobazco.org # [SPARC32]: Small SMP build fixes # # include/asm-sparc/system.h # 2004/02/23 21:56:54-08:00 wesolows@foobazco.org +1 -1 # [SPARC32]: SMP build fixes # # arch/sparc/mm/nosun4c.c # 2004/02/23 21:56:54-08:00 wesolows@foobazco.org +5 -0 # [SPARC32]: SMP build fixes # # arch/sparc/kernel/trampoline.S # 2004/02/23 21:56:54-08:00 wesolows@foobazco.org +1 -0 # [SPARC32]: SMP build fixes # # arch/sparc/kernel/sparc_ksyms.c # 2004/02/23 21:56:54-08:00 wesolows@foobazco.org +0 -1 # [SPARC32]: SMP build fixes # diff -Nru a/Documentation/cdrom/ide-cd b/Documentation/cdrom/ide-cd --- a/Documentation/cdrom/ide-cd Sun Mar 7 18:39:37 2004 +++ b/Documentation/cdrom/ide-cd Sun Mar 7 18:39:37 2004 @@ -74,7 +74,7 @@ 3. The CDROM drive should be connected to the host on an IDE interface. Each interface on a system is defined by an I/O port address and an IRQ number, the standard assignments being - 0x170 and 14 for the primary interface and 0x1f0 and 15 for the + 0x1f0 and 14 for the primary interface and 0x170 and 15 for the secondary interface. Each interface can control up to two devices, where each device can be a hard drive, a CDROM drive, a floppy drive, or a tape drive. The two devices on an interface are called `master' @@ -268,8 +268,8 @@ - Double-check your hardware configuration to make sure that the IRQ number of your IDE interface matches what the driver expects. - (The usual assignments are 14 for the primary (0x170) interface - and 15 for the secondary (0x1f0) interface.) Also be sure that + (The usual assignments are 14 for the primary (0x1f0) interface + and 15 for the secondary (0x170) interface.) Also be sure that you don't have some other hardware which might be conflicting with the IRQ you're using. Also check the BIOS setup for your system; some have the ability to disable individual IRQ levels, and I've diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt --- a/Documentation/crypto/api-intro.txt Sun Mar 7 18:39:37 2004 +++ b/Documentation/crypto/api-intro.txt Sun Mar 7 18:39:37 2004 @@ -186,6 +186,7 @@ Dag Arne Osvik (Serpent) Brian Gladman (AES) Kartikey Mahendra Bhatt (CAST6) + Jon Oberheide (ARC4) SHA1 algorithm contributors: Jean-Francois Dive diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt --- a/Documentation/kernel-parameters.txt Sun Mar 7 18:39:38 2004 +++ b/Documentation/kernel-parameters.txt Sun Mar 7 18:39:38 2004 @@ -90,10 +90,13 @@ Format: , default is 13 acpi= [HW,ACPI] Advanced Configuration and Power Interface - Format: { force | off | ht } + Format: { force | off | ht | strict } force -- enables ACPI for systems with default off off -- disabled ACPI for systems with default on ht -- run only enough ACPI to enable Hyper Threading + strict -- Be less tolerant of platforms that are not + strictly ACPI specification compliant. + See also Documentation/pm.txt. acpi_pic_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sun Mar 7 18:39:37 2004 +++ b/MAINTAINERS Sun Mar 7 18:39:37 2004 @@ -172,7 +172,7 @@ P: Len Brown M: len.brown@intel.com L: acpi-devel@lists.sourceforge.net -W: http://sf.net/projects/acpi/ +W: http://acpi.sourceforge.net/ S: Maintained AD1816 SOUND DRIVER diff -Nru a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c --- a/arch/alpha/kernel/ptrace.c Sun Mar 7 18:39:38 2004 +++ b/arch/alpha/kernel/ptrace.c Sun Mar 7 18:39:38 2004 @@ -369,8 +369,8 @@ /* Mark single stepping. */ child->thread_info->bpt_nsaved = -1; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - wake_up_process(child); child->exit_code = data; + wake_up_process(child); /* give it a chance to run. */ ret = 0; goto out; diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile Sun Mar 7 18:39:37 2004 +++ b/arch/arm/Makefile Sun Mar 7 18:39:37 2004 @@ -23,6 +23,11 @@ AS += -EB LD += -EB AFLAGS += -mbig-endian +else +CFLAGS += -mlittle-endian +AS += -EL +LD += -EL +AFLAGS += -mlittle-endian endif comma = , diff -Nru a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c --- a/arch/arm/kernel/armksyms.c Sun Mar 7 18:39:37 2004 +++ b/arch/arm/kernel/armksyms.c Sun Mar 7 18:39:37 2004 @@ -187,6 +187,7 @@ EXPORT_SYMBOL(__arch_copy_to_user); EXPORT_SYMBOL(__arch_clear_user); EXPORT_SYMBOL(__arch_strnlen_user); +EXPORT_SYMBOL(__arch_strncpy_from_user); /* consistent area handling */ EXPORT_SYMBOL(consistent_alloc); diff -Nru a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig --- a/arch/arm/mm/Kconfig Sun Mar 7 18:39:37 2004 +++ b/arch/arm/mm/Kconfig Sun Mar 7 18:39:37 2004 @@ -347,7 +347,7 @@ help Say Y if you plan on running a kernel in big-endian mode. Note that your board must be properly built and your board - port must properly enable and big-endian related features + port must properly enable any big-endian related features of your chipset/board/processor. config CPU_ICACHE_DISABLE diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Sun Mar 7 18:39:36 2004 +++ b/arch/i386/Kconfig Sun Mar 7 18:39:36 2004 @@ -1068,12 +1068,16 @@ PCI-based systems don't have any BIOS at all. Linux can also try to detect the PCI hardware directly without using the BIOS. - With this option, you can specify how Linux should detect the PCI - devices. If you choose "BIOS", the BIOS will be used, if you choose - "Direct", the BIOS won't be used, and if you choose "Any", the - kernel will try the direct access method and falls back to the BIOS - if that doesn't work. If unsure, go with the default, which is - "Any". + With this option, you can specify how Linux should detect the + PCI devices. If you choose "BIOS", the BIOS will be used, + if you choose "Direct", the BIOS won't be used, and if you + choose "MMConfig", then PCI Express MMCONFIG will be used. + If you choose "Any", the kernel will try MMCONFIG, then the + direct access method and falls back to the BIOS if that doesn't + work. If unsure, go with the default, which is "Any". + +config PCI_GOMMCONFIG + bool "MMConfig" config PCI_GODIRECT bool "Direct" @@ -1091,6 +1095,12 @@ config PCI_DIRECT bool depends on PCI && ((PCI_GODIRECT || PCI_GOANY) || X86_VISWS) + default y + +config PCI_MMCONFIG + bool + depends on PCI && (PCI_GOMMCONFIG || PCI_GOANY) + select ACPI_BOOT default y config PCI_USE_VECTOR diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c --- a/arch/i386/kernel/acpi/boot.c Sun Mar 7 18:39:38 2004 +++ b/arch/i386/kernel/acpi/boot.c Sun Mar 7 18:39:38 2004 @@ -35,7 +35,7 @@ #include #include -#if defined (CONFIG_X86_LOCAL_APIC) +#ifdef CONFIG_X86_LOCAL_APIC #include #include #include @@ -43,17 +43,26 @@ #define PREFIX "ACPI: " -int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */ +int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ int acpi_ht __initdata = 1; /* enable HT */ int acpi_lapic; int acpi_ioapic; +int acpi_strict; + +#ifdef CONFIG_X86_LOCAL_APIC +static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; +#endif /* -------------------------------------------------------------------------- Boot-time Configuration -------------------------------------------------------------------------- */ -enum acpi_irq_model_id acpi_irq_model; +/* + * The default interrupt routing model is PIC (8259). This gets + * overriden if IOAPICs are enumerated (below). + */ +enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC; /* * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END, @@ -96,11 +105,32 @@ } -#ifdef CONFIG_X86_LOCAL_APIC +#ifdef CONFIG_PCI_MMCONFIG +static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_mcfg *mcfg; -static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; + if (!phys_addr || !size) + return -EINVAL; + + mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); + if (!mcfg) { + printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); + return -ENODEV; + } + if (mcfg->base_reserved) { + printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + + pci_mmcfg_base_addr = mcfg->base_address; + + return 0; +} +#endif /* CONFIG_PCI_MMCONFIG */ +#ifdef CONFIG_X86_LOCAL_APIC static int __init acpi_parse_madt ( unsigned long phys_addr, @@ -117,11 +147,12 @@ return -ENODEV; } - if (madt->lapic_address) + if (madt->lapic_address) { acpi_lapic_addr = (u64) madt->lapic_address; - printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", - madt->lapic_address); + printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n", + madt->lapic_address); + } acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -251,7 +282,7 @@ return 0; } -#endif /*CONFIG_X86_IO_APIC*/ +#endif /* CONFIG_X86_IO_APIC */ #ifdef CONFIG_ACPI_BUS /* @@ -259,7 +290,7 @@ * programs the PIC-mode SCI to Level Trigger. * (NO-OP if the BIOS set Level Trigger already) * - * If a PIC-mode SCI is not recogznied or gives spurious IRQ7's + * If a PIC-mode SCI is not recognized or gives spurious IRQ7's * it may require Edge Trigger -- use "acpi_pic_sci=edge" * (NO-OP if the BIOS set Edge Trigger already) * @@ -347,6 +378,25 @@ return 0; } +static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) +{ + struct acpi_table_sbf *sb; + + if (!phys_addr || !size) + return -EINVAL; + + sb = (struct acpi_table_sbf *) __acpi_map_table(phys_addr, size); + if (!sb) { + printk(KERN_WARNING PREFIX "Unable to map SBF\n"); + return -ENODEV; + } + + sbf_port = sb->sbf_cmos; /* Save CMOS port */ + + return 0; +} + + #ifdef CONFIG_HPET_TIMER extern unsigned long hpet_address; @@ -429,126 +479,61 @@ return rsdp_phys; } +#ifdef CONFIG_X86_LOCAL_APIC /* - * acpi_boot_init() - * called from setup_arch(), always. - * 1. maps ACPI tables for later use - * 2. enumerates lapics - * 3. enumerates io-apics - * - * side effects: - * acpi_lapic = 1 if LAPIC found - * acpi_ioapic = 1 if IOAPIC found - * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; - * if acpi_blacklisted() acpi_disabled = 1; - * acpi_irq_model=... - * ... - * - * return value: (currently ignored) - * 0: success - * !0: failure + * Parse LAPIC entries in MADT + * returns 0 on success, < 0 on error */ - -int __init -acpi_boot_init (void) +static int __init +acpi_parse_madt_lapic_entries(void) { - int result = 0; - - if (acpi_disabled && !acpi_ht) - return 1; - - /* - * The default interrupt routing model is PIC (8259). This gets - * overriden if IOAPICs are enumerated (below). - */ - acpi_irq_model = ACPI_IRQ_MODEL_PIC; - - /* - * Initialize the ACPI boot-time table parser. - */ - result = acpi_table_init(); - if (result) { - acpi_disabled = 1; - return result; - } - - result = acpi_blacklisted(); - if (result) { - printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); - acpi_disabled = 1; - return result; - } - -#ifdef CONFIG_X86_PM_TIMER - acpi_table_parse(ACPI_FADT, acpi_parse_fadt); -#endif - -#ifdef CONFIG_X86_LOCAL_APIC - - /* - * MADT - * ---- - * Parse the Multiple APIC Description Table (MADT), if exists. - * Note that this table provides platform SMP configuration - * information -- the successor to MPS tables. - */ - - result = acpi_table_parse(ACPI_APIC, acpi_parse_madt); - if (!result) { - return 0; - } - else if (result < 0) { - printk(KERN_ERR PREFIX "Error parsing MADT\n"); - return result; - } - else if (result > 1) - printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n"); + int count; /* - * Local APIC - * ---------- * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). */ - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); - return result; + return count; } mp_register_lapic_address(acpi_lapic_addr); - result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, + count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic, MAX_APICS); - if (!result) { + if (!count) { printk(KERN_ERR PREFIX "No LAPIC entries present\n"); /* TBD: Cleanup to allow fallback to MPS */ return -ENODEV; } - else if (result < 0) { + else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - - acpi_lapic = 1; - -#endif /*CONFIG_X86_LOCAL_APIC*/ + return 0; +} +#endif /* CONFIG_X86_LOCAL_APIC */ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI_INTERPRETER) - - /* - * I/O APIC - * -------- - */ +/* + * Parse IOAPIC related entries in MADT + * returns 0 on success, < 0 on error + */ +static int __init +acpi_parse_madt_ioapic_entries(void) +{ + int count; /* * ACPI interpreter is required to complete interrupt setup, @@ -557,7 +542,7 @@ * otherwise the system will stay in PIC mode */ if (acpi_disabled || acpi_noirq) { - return 1; + return -ENODEV; } /* @@ -566,54 +551,152 @@ if (ioapic_setup_disabled()) { printk(KERN_INFO PREFIX "Skipping IOAPIC probe " "due to 'noapic' option.\n"); - return 1; + return -ENODEV; } - result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); - if (!result) { + count = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS); + if (!count) { printk(KERN_ERR PREFIX "No IOAPIC entries present\n"); return -ENODEV; } - else if (result < 0) { + else if (count < 0) { printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n"); - return result; + return count; } /* Build a default routing table for legacy (ISA) interrupts. */ mp_config_acpi_legacy_irqs(); - result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); - if (result < 0) { + count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS); + if (count < 0) { printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); /* TBD: Cleanup to allow fallback to MPS */ - return result; + return count; } - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + return 0; +} +#else +static inline int acpi_parse_madt_ioapic_entries(void) +{ + return -1; +} +#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */ - acpi_irq_balance_set(NULL); - acpi_ioapic = 1; +static void __init +acpi_process_madt(void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + int count, error; -#endif /* CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER */ + count = acpi_table_parse(ACPI_APIC, acpi_parse_madt); + if (count == 1) { -#ifdef CONFIG_X86_LOCAL_APIC - if (acpi_lapic && acpi_ioapic) { - smp_found_config = 1; - clustered_apic_check(); + /* + * Parse MADT LAPIC entries + */ + error = acpi_parse_madt_lapic_entries(); + if (!error) { + acpi_lapic = 1; + + /* + * Parse MADT IO-APIC entries + */ + error = acpi_parse_madt_ioapic_entries(); + if (!error) { + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; + acpi_irq_balance_set(NULL); + acpi_ioapic = 1; + + smp_found_config = 1; + clustered_apic_check(); + } + } } #endif + return; +} + +/* + * acpi_boot_init() + * called from setup_arch(), always. + * 1. checksums all tables + * 2. enumerates lapics + * 3. enumerates io-apics + * + * side effects: + * acpi_lapic = 1 if LAPIC found + * acpi_ioapic = 1 if IOAPIC found + * if (acpi_lapic && acpi_ioapic) smp_found_config = 1; + * if acpi_blacklisted() acpi_disabled = 1; + * acpi_irq_model=... + * ... + * + * return value: (currently ignored) + * 0: success + * !0: failure + */ + +int __init +acpi_boot_init (void) +{ + int error; + + /* + * If acpi_disabled, bail out + * One exception: acpi=ht continues far enough to enumerate LAPICs + */ + if (acpi_disabled && !acpi_ht) + return 1; + + /* + * Initialize the ACPI boot-time table parser. + */ + error = acpi_table_init(); + if (error) { + acpi_disabled = 1; + return error; + } + + (void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); + + /* + * blacklist may disable ACPI entirely + */ + error = acpi_blacklisted(); + if (error) { + printk(KERN_WARNING PREFIX "BIOS listed in blacklist, disabling ACPI support\n"); + acpi_disabled = 1; + return error; + } + + /* + * Process the Multiple APIC Description Table (MADT), if present + */ + acpi_process_madt(); + +#ifdef CONFIG_X86_PM_TIMER + acpi_table_parse(ACPI_FADT, acpi_parse_fadt); +#endif #ifdef CONFIG_HPET_TIMER - acpi_table_parse(ACPI_HPET, acpi_parse_hpet); + (void) acpi_table_parse(ACPI_HPET, acpi_parse_hpet); +#endif + +#ifdef CONFIG_PCI_MMCONFIG + error = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if (error) + printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", error); #endif return 0; } + diff -Nru a/arch/i386/kernel/bootflag.c b/arch/i386/kernel/bootflag.c --- a/arch/i386/kernel/bootflag.c Sun Mar 7 18:39:37 2004 +++ b/arch/i386/kernel/bootflag.c Sun Mar 7 18:39:37 2004 @@ -1,6 +1,5 @@ /* - * Implement 'Simple Boot Flag Specification 1.0' - * + * Implement 'Simple Boot Flag Specification 2.0' */ @@ -11,6 +10,7 @@ #include #include #include +#include #include #include @@ -23,56 +23,8 @@ #define SBF_PARITY (1<<7) -struct sbf_boot -{ - u8 sbf_signature[4]; - u32 sbf_len; - u8 sbf_revision __attribute((packed)); - u8 sbf_csum __attribute((packed)); - u8 sbf_oemid[6] __attribute((packed)); - u8 sbf_oemtable[8] __attribute((packed)); - u8 sbf_revdata[4] __attribute((packed)); - u8 sbf_creator[4] __attribute((packed)); - u8 sbf_crearev[4] __attribute((packed)); - u8 sbf_cmos __attribute((packed)); - u8 sbf_spare[3] __attribute((packed)); -}; - - -static int sbf_port __initdata = -1; - -static int __init sbf_struct_valid(unsigned long tptr) -{ - u8 *ap; - u8 v; - unsigned int i; - struct sbf_boot sb; - - memcpy_fromio(&sb, (void *)tptr, sizeof(sb)); - - if(sb.sbf_len != 40 && sb.sbf_len != 39) - // 39 on IBM ThinkPad A21m, BIOS version 1.02b (KXET24WW; 2000-12-19). - return 0; - - ap = (u8 *)&sb; - v= 0; - - for(i=0;i1) - rsdtlen = *(u32 *)(p+20); - else - rsdtlen = 36; - - if(rsdtlen < 36 || rsdtlen > 1024) - continue; - break; - } - if(i>0xFFFE0) - return 0; - - - rsdt = ioremap(rsdtbase, rsdtlen); - if(rsdt == 0) - return 0; - - i = readl(rsdt + 4); - - /* - * Remap if needed - */ - - if(i > rsdtlen) - { - rsdtlen = i; - iounmap(rsdt); - rsdt = ioremap(rsdtbase, rsdtlen); - if(rsdt == 0) - return 0; - } - - for(n = 0; n < i; n++) - sum += readb(rsdt + n); - - if(sum) - { - iounmap(rsdt); - return 0; - } - - /* Ok the RSDT checksums too */ - - for(n = 36; n+3 < i; n += 4) - { - unsigned long rp = readl(rsdt+n); - int len = 4096; - - if(rp > 0xFFFFFFFFUL - len) - len = 0xFFFFFFFFUL - rp; - - /* Too close to the end!! */ - if(len < 20) - continue; - rp = (unsigned long)ioremap(rp, 4096); - if(rp == 0) - continue; - if(sbf_struct_valid(rp)) - { - /* Found the BOOT table and processed it */ - printk(KERN_INFO "SBF: Simple Boot Flag extension found and enabled.\n"); - } - iounmap((void *)rp); - } - iounmap(rsdt); - sbf_bootup(); return 0; } diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c Sun Mar 7 18:39:37 2004 +++ b/arch/i386/kernel/mpparse.c Sun Mar 7 18:39:37 2004 @@ -1156,7 +1156,7 @@ continue; } if ((1<irq = acpi_irq_to_vector(irq); continue; diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c --- a/arch/i386/kernel/process.c Sun Mar 7 18:39:36 2004 +++ b/arch/i386/kernel/process.c Sun Mar 7 18:39:36 2004 @@ -493,7 +493,7 @@ * the task-switch, and shows up in ret_from_fork in entry.S, * for example. */ -struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) +struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) { struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Sun Mar 7 18:39:37 2004 +++ b/arch/i386/kernel/setup.c Sun Mar 7 18:39:37 2004 @@ -569,6 +569,11 @@ acpi_disabled = 0; } + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } + /* Limit ACPI just to boot-time to enable HT */ else if (!memcmp(from, "acpi=ht", 7)) { acpi_ht = 1; diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c --- a/arch/i386/kernel/signal.c Sun Mar 7 18:39:37 2004 +++ b/arch/i386/kernel/signal.c Sun Mar 7 18:39:37 2004 @@ -551,7 +551,7 @@ * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c --- a/arch/i386/kernel/smp.c Sun Mar 7 18:39:36 2004 +++ b/arch/i386/kernel/smp.c Sun Mar 7 18:39:36 2004 @@ -150,7 +150,7 @@ apic_write_around(APIC_ICR, cfg); } -void send_IPI_self(int vector) +void fastcall send_IPI_self(int vector) { __send_IPI_shortcut(APIC_DEST_SELF, vector); } diff -Nru a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c --- a/arch/i386/kernel/vm86.c Sun Mar 7 18:39:36 2004 +++ b/arch/i386/kernel/vm86.c Sun Mar 7 18:39:36 2004 @@ -95,7 +95,7 @@ #define VM86_REGS_SIZE2 (sizeof(struct kernel_vm86_regs) - VM86_REGS_SIZE1) struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); -struct pt_regs * save_v86_state(struct kernel_vm86_regs * regs) +struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) { struct tss_struct *tss; struct pt_regs *ret; diff -Nru a/arch/i386/mm/extable.c b/arch/i386/mm/extable.c --- a/arch/i386/mm/extable.c Sun Mar 7 18:39:38 2004 +++ b/arch/i386/mm/extable.c Sun Mar 7 18:39:38 2004 @@ -12,7 +12,7 @@ const struct exception_table_entry *fixup; #ifdef CONFIG_PNPBIOS - if (unlikely((regs->xcs | 8) == 0x88)) /* 0x80 or 0x88 */ + if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3))) { extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; extern u32 pnp_bios_is_utter_crap; @@ -21,7 +21,7 @@ __asm__ volatile( "movl %0, %%esp\n\t" "jmp *%1\n\t" - : "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip)); + : : "g" (pnp_bios_fault_esp), "g" (pnp_bios_fault_eip)); panic("do_trap: can't hit this"); } #endif diff -Nru a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile --- a/arch/i386/pci/Makefile Sun Mar 7 18:39:37 2004 +++ b/arch/i386/pci/Makefile Sun Mar 7 18:39:37 2004 @@ -1,6 +1,7 @@ obj-y := i386.o obj-$(CONFIG_PCI_BIOS) += pcbios.o +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o obj-$(CONFIG_PCI_DIRECT) += direct.o pci-y := fixup.o diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c --- a/arch/i386/pci/common.c Sun Mar 7 18:39:37 2004 +++ b/arch/i386/pci/common.c Sun Mar 7 18:39:37 2004 @@ -20,7 +20,8 @@ extern void pcibios_sort(void); #endif -unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2; +unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | + PCI_PROBE_MMCONF; int pcibios_last_bus = -1; struct pci_bus *pci_root_bus = NULL; @@ -195,6 +196,12 @@ } else if (!strcmp(str, "conf2")) { pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS; + return NULL; + } +#endif +#ifdef CONFIG_PCI_MMCONFIG + else if (!strcmp(str, "nommconf")) { + pci_probe &= ~PCI_PROBE_MMCONF; return NULL; } #endif diff -Nru a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/pci/mmconfig.c Sun Mar 7 18:39:38 2004 @@ -0,0 +1,109 @@ +/* + * mmconfig.c - Low-level direct PCI config space access via MMCONFIG + */ + +#include +#include +#include "pci.h" + +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +u32 pci_mmcfg_base_addr; + +#define mmcfg_virt_addr (fix_to_virt(FIX_PCIE_MCFG)) + +/* The base address of the last MMCONFIG device accessed */ +static u32 mmcfg_last_accessed_device; + +/* + * Functions for accessing PCI configuration space with MMCONFIG accesses + */ + +static inline void pci_exp_set_dev_base(int bus, int devfn) +{ + u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + if (dev_base != mmcfg_last_accessed_device) { + mmcfg_last_accessed_device = dev_base; + set_fixmap(FIX_PCIE_MCFG, dev_base); + } +} + +static int pci_mmcfg_read(int seg, int bus, int devfn, int reg, int len, u32 *value) +{ + unsigned long flags; + + if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + pci_exp_set_dev_base(bus, devfn); + + switch (len) { + case 1: + *value = readb(mmcfg_virt_addr + reg); + break; + case 2: + *value = readw(mmcfg_virt_addr + reg); + break; + case 4: + *value = readl(mmcfg_virt_addr + reg); + break; + } + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + +static int pci_mmcfg_write(int seg, int bus, int devfn, int reg, int len, u32 value) +{ + unsigned long flags; + + if ((bus > 255) || (devfn > 255) || (reg > 4095)) + return -EINVAL; + + spin_lock_irqsave(&pci_config_lock, flags); + + pci_exp_set_dev_base(bus, devfn); + + switch (len) { + case 1: + writeb(value, mmcfg_virt_addr + reg); + break; + case 2: + writew(value, mmcfg_virt_addr + reg); + break; + case 4: + writel(value, mmcfg_virt_addr + reg); + break; + } + + /* Dummy read to flush PCI write */ + readl(mmcfg_virt_addr); + + spin_unlock_irqrestore(&pci_config_lock, flags); + + return 0; +} + +static struct pci_raw_ops pci_mmcfg = { + .read = pci_mmcfg_read, + .write = pci_mmcfg_write, +}; + +static int __init pci_mmcfg_init(void) +{ + if ((pci_probe & PCI_PROBE_MMCONF) == 0) + goto out; + if (!pci_mmcfg_base_addr) + goto out; + + printk(KERN_INFO "PCI: Using MMCONFIG\n"); + raw_pci_ops = &pci_mmcfg; + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; + + out: + return 0; +} + +arch_initcall(pci_mmcfg_init); diff -Nru a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h --- a/arch/i386/pci/pci.h Sun Mar 7 18:39:37 2004 +++ b/arch/i386/pci/pci.h Sun Mar 7 18:39:37 2004 @@ -15,6 +15,9 @@ #define PCI_PROBE_BIOS 0x0001 #define PCI_PROBE_CONF1 0x0002 #define PCI_PROBE_CONF2 0x0004 +#define PCI_PROBE_MMCONF 0x0008 +#define PCI_PROBE_MASK 0x000f + #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 #define PCI_NO_CHECKS 0x0400 diff -Nru a/arch/mips/kernel/ioctl32.c b/arch/mips/kernel/ioctl32.c --- a/arch/mips/kernel/ioctl32.c Sun Mar 7 18:39:37 2004 +++ b/arch/mips/kernel/ioctl32.c Sun Mar 7 18:39:37 2004 @@ -1277,20 +1277,6 @@ COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL) #endif /* CONFIG_SIBYTE_TBPROF */ -#if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE) -COMPATIBLE_IOCTL(DM_VERSION) -COMPATIBLE_IOCTL(DM_REMOVE_ALL) -COMPATIBLE_IOCTL(DM_DEV_CREATE) -COMPATIBLE_IOCTL(DM_DEV_REMOVE) -COMPATIBLE_IOCTL(DM_DEV_RELOAD) -COMPATIBLE_IOCTL(DM_DEV_SUSPEND) -COMPATIBLE_IOCTL(DM_DEV_RENAME) -COMPATIBLE_IOCTL(DM_DEV_DEPS) -COMPATIBLE_IOCTL(DM_DEV_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_WAIT) -#endif /* CONFIG_BLK_DEV_DM */ - COMPATIBLE_IOCTL(MTIOCTOP) /* mtio.h ioctls */ HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) diff -Nru a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S --- a/arch/ppc/kernel/head.S Sun Mar 7 18:39:37 2004 +++ b/arch/ppc/kernel/head.S Sun Mar 7 18:39:37 2004 @@ -1492,22 +1492,22 @@ * seems that doesn't affect our ability to actually * write to these SPRs. */ - mtspr SPRN_DBAT4U,r20 - mtspr SPRN_DBAT4L,r20 - mtspr SPRN_DBAT5U,r20 - mtspr SPRN_DBAT5L,r20 - mtspr SPRN_DBAT6U,r20 - mtspr SPRN_DBAT6L,r20 - mtspr SPRN_DBAT7U,r20 - mtspr SPRN_DBAT7L,r20 - mtspr SPRN_IBAT4U,r20 - mtspr SPRN_IBAT4L,r20 - mtspr SPRN_IBAT5U,r20 - mtspr SPRN_IBAT5L,r20 - mtspr SPRN_IBAT6U,r20 - mtspr SPRN_IBAT6L,r20 - mtspr SPRN_IBAT7U,r20 - mtspr SPRN_IBAT7L,r20 + mtspr SPRN_DBAT4U,r10 + mtspr SPRN_DBAT4L,r10 + mtspr SPRN_DBAT5U,r10 + mtspr SPRN_DBAT5L,r10 + mtspr SPRN_DBAT6U,r10 + mtspr SPRN_DBAT6L,r10 + mtspr SPRN_DBAT7U,r10 + mtspr SPRN_DBAT7L,r10 + mtspr SPRN_IBAT4U,r10 + mtspr SPRN_IBAT4L,r10 + mtspr SPRN_IBAT5U,r10 + mtspr SPRN_IBAT5L,r10 + mtspr SPRN_IBAT6U,r10 + mtspr SPRN_IBAT6L,r10 + mtspr SPRN_IBAT7U,r10 + mtspr SPRN_IBAT7L,r10 END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) blr diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/Kconfig Sun Mar 7 18:39:37 2004 @@ -300,10 +300,6 @@ If you are running Linux on an IBM iSeries system and you want to read a CD drive owned by OS/400, say Y here. -config VIOCD_AZTECH - bool "iSeries Virtual CD Aztech emulation" - depends on VIOCD - config VIOTAPE tristate "iSeries Virtual Tape Support" help diff -Nru a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c --- a/arch/ppc64/kernel/iSeries_iommu.c Sun Mar 7 18:39:36 2004 +++ b/arch/ppc64/kernel/iSeries_iommu.c Sun Mar 7 18:39:36 2004 @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -58,11 +59,6 @@ static struct pci_dev _veth_dev = { .sysdata = &veth_dev_node }; static struct pci_dev _vio_dev = { .sysdata = &vio_dev_node, .dev.bus = &pci_bus_type }; -/* - * I wonder what the deal is with these. Nobody uses them. Why do they - * exist? Why do we export them to modules? Why is this comment here, and - * why didn't I just delete them? - */ struct pci_dev *iSeries_veth_dev = &_veth_dev; struct device *iSeries_vio_dev = &_vio_dev.dev; diff -Nru a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c --- a/arch/ppc64/kernel/mf.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/kernel/mf.c Sun Mar 7 18:39:37 2004 @@ -38,10 +38,9 @@ #include #include #include -#include +#include #include - -extern struct pci_dev *iSeries_vio_dev; +#include /* * This is the structure layout for the Machine Facilites LPAR event @@ -791,7 +790,8 @@ { struct VspCmdData myVspCmd; dma_addr_t dma_addr = 0; - char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr); + char *page = dma_alloc_coherent(iSeries_vio_dev, size, &dma_addr, + GFP_ATOMIC); if (page == NULL) { printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n"); @@ -809,7 +809,7 @@ mb(); (void)signal_vsp_instruction(&myVspCmd); - pci_free_consistent(iSeries_vio_dev, size, page, dma_addr); + dma_free_coherent(iSeries_vio_dev, size, page, dma_addr); } int mf_getCmdLine(char *cmdline, int *size, u64 side) @@ -819,8 +819,8 @@ int len = *size; dma_addr_t dma_addr; - dma_addr = pci_map_single(iSeries_vio_dev, cmdline, len, - PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(iSeries_vio_dev, cmdline, len, + DMA_FROM_DEVICE); memset(cmdline, 0, len); memset(&myVspCmd, 0, sizeof(myVspCmd)); myVspCmd.cmd = 33; @@ -840,7 +840,7 @@ #endif } - pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE); + dma_unmap_single(iSeries_vio_dev, dma_addr, *size, DMA_FROM_DEVICE); return len; } @@ -851,7 +851,8 @@ struct VspCmdData myVspCmd; int rc; dma_addr_t dma_addr = 0; - char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr); + char *page = dma_alloc_coherent(iSeries_vio_dev, size, &dma_addr, + GFP_ATOMIC); if (page == NULL) { printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); @@ -876,7 +877,7 @@ rc = -ENOMEM; } - pci_free_consistent(iSeries_vio_dev, size, page, dma_addr); + dma_free_coherent(iSeries_vio_dev, size, page, dma_addr); return rc; } @@ -888,8 +889,8 @@ int len = *size; dma_addr_t dma_addr; - dma_addr = pci_map_single(iSeries_vio_dev, buffer, len, - PCI_DMA_FROMDEVICE); + dma_addr = dma_map_single(iSeries_vio_dev, buffer, len, + DMA_FROM_DEVICE); memset(buffer, 0, len); memset(&myVspCmd, 0, sizeof(myVspCmd)); myVspCmd.cmd = 32; @@ -907,7 +908,7 @@ rc = -ENOMEM; } - pci_unmap_single(iSeries_vio_dev, dma_addr, len, PCI_DMA_FROMDEVICE); + dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE); return rc; } diff -Nru a/arch/ppc64/kernel/stab.c b/arch/ppc64/kernel/stab.c --- a/arch/ppc64/kernel/stab.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/kernel/stab.c Sun Mar 7 18:39:37 2004 @@ -184,13 +184,13 @@ /* Kernel or user address? */ if (REGION_ID(ea) >= KERNEL_REGION_ID) { vsid = get_kernel_vsid(ea); - context = REGION_ID(ea); + context = KERNEL_CONTEXT(ea); } else { if (!current->mm) return 1; context = current->mm->context; - vsid = get_vsid(context, ea); + vsid = get_vsid(context.id, ea); } esid = GET_ESID(ea); @@ -223,7 +223,7 @@ if (!IS_VALID_EA(pc) || (REGION_ID(pc) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, pc); + vsid = get_vsid(mm->context.id, pc); __ste_allocate(pc_esid, vsid); if (pc_esid == stack_esid) @@ -231,7 +231,7 @@ if (!IS_VALID_EA(stack) || (REGION_ID(stack) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, stack); + vsid = get_vsid(mm->context.id, stack); __ste_allocate(stack_esid, vsid); if (pc_esid == unmapped_base_esid || stack_esid == unmapped_base_esid) @@ -240,7 +240,7 @@ if (!IS_VALID_EA(unmapped_base) || (REGION_ID(unmapped_base) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, unmapped_base); + vsid = get_vsid(mm->context.id, unmapped_base); __ste_allocate(unmapped_base_esid, vsid); /* Order update */ @@ -406,14 +406,14 @@ /* Kernel or user address? */ if (REGION_ID(ea) >= KERNEL_REGION_ID) { - context = REGION_ID(ea); + context = KERNEL_CONTEXT(ea); vsid = get_kernel_vsid(ea); } else { if (unlikely(!current->mm)) return 1; context = current->mm->context; - vsid = get_vsid(context, ea); + vsid = get_vsid(context.id, ea); } esid = GET_ESID(ea); @@ -444,7 +444,7 @@ if (!IS_VALID_EA(pc) || (REGION_ID(pc) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, pc); + vsid = get_vsid(mm->context.id, pc); __slb_allocate(pc_esid, vsid, mm->context); if (pc_esid == stack_esid) @@ -452,7 +452,7 @@ if (!IS_VALID_EA(stack) || (REGION_ID(stack) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, stack); + vsid = get_vsid(mm->context.id, stack); __slb_allocate(stack_esid, vsid, mm->context); if (pc_esid == unmapped_base_esid || stack_esid == unmapped_base_esid) @@ -461,7 +461,7 @@ if (!IS_VALID_EA(unmapped_base) || (REGION_ID(unmapped_base) >= KERNEL_REGION_ID)) return; - vsid = get_vsid(mm->context, unmapped_base); + vsid = get_vsid(mm->context.id, unmapped_base); __slb_allocate(unmapped_base_esid, vsid, mm->context); } diff -Nru a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c --- a/arch/ppc64/kernel/viopath.c Sun Mar 7 18:39:36 2004 +++ b/arch/ppc64/kernel/viopath.c Sun Mar 7 18:39:36 2004 @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -48,8 +47,6 @@ #include #include #include - -extern struct device *iSeries_vio_dev; /* Status of the path to each other partition in the system. * This is overkill, since we will only ever establish connections diff -Nru a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c --- a/arch/ppc64/mm/hash_utils.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/mm/hash_utils.c Sun Mar 7 18:39:37 2004 @@ -265,7 +265,7 @@ if (mm == NULL) return 1; - vsid = get_vsid(mm->context, ea); + vsid = get_vsid(mm->context.id, ea); break; case IO_REGION_ID: mm = &ioremap_mm; diff -Nru a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c --- a/arch/ppc64/mm/hugetlbpage.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/mm/hugetlbpage.c Sun Mar 7 18:39:37 2004 @@ -244,7 +244,7 @@ struct vm_area_struct *vma; unsigned long addr; - if (mm->context & CONTEXT_LOW_HPAGES) + if (mm->context.low_hpages) return 0; /* The window is already open */ /* Check no VMAs are in the region */ @@ -281,7 +281,7 @@ /* FIXME: do we need to scan for PTEs too? */ - mm->context |= CONTEXT_LOW_HPAGES; + mm->context.low_hpages = 1; /* the context change must make it to memory before the slbia, * so that further SLB misses do the right thing. */ @@ -589,7 +589,6 @@ } } - unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) @@ -778,7 +777,7 @@ BUG_ON(hugepte_bad(pte)); BUG_ON(!in_hugepage_area(context, ea)); - vsid = get_vsid(context, ea); + vsid = get_vsid(context.id, ea); va = (vsid << 28) | (ea & 0x0fffffff); vpn = va >> LARGE_PAGE_SHIFT; diff -Nru a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c --- a/arch/ppc64/mm/init.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/mm/init.c Sun Mar 7 18:39:37 2004 @@ -794,7 +794,7 @@ if (!ptep) return; - vsid = get_vsid(vma->vm_mm->context, ea); + vsid = get_vsid(vma->vm_mm->context.id, ea); tmp = cpumask_of_cpu(smp_processor_id()); if (cpus_equal(vma->vm_mm->cpu_vm_mask, tmp)) diff -Nru a/arch/ppc64/mm/tlb.c b/arch/ppc64/mm/tlb.c --- a/arch/ppc64/mm/tlb.c Sun Mar 7 18:39:37 2004 +++ b/arch/ppc64/mm/tlb.c Sun Mar 7 18:39:37 2004 @@ -62,7 +62,7 @@ addr = ptep_to_address(ptep); if (REGION_ID(addr) == USER_REGION_ID) - context = mm->context; + context = mm->context.id; i = batch->index; /* diff -Nru a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c --- a/arch/ppc64/xmon/xmon.c Sun Mar 7 18:39:38 2004 +++ b/arch/ppc64/xmon/xmon.c Sun Mar 7 18:39:38 2004 @@ -344,7 +344,7 @@ #endif /* CONFIG_SMP */ set_msrd(msr); /* restore interrupt enable */ - return 0; + return 1; } int diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig --- a/arch/sparc/Kconfig Sun Mar 7 18:39:36 2004 +++ b/arch/sparc/Kconfig Sun Mar 7 18:39:36 2004 @@ -380,11 +380,32 @@ menu "Kernel hacking" +config DEBUG_KERNEL + bool "Kernel debugging" + help + Say Y here if you are developing drivers or trying to debug and + identify kernel problems. + +config DEBUG_STACK_USAGE + bool "Enable stack utilization instrumentation" + depends on DEBUG_KERNEL + help + Enables the display of the minimum amount of free stack which each + task has ever had available in the sysrq-T and sysrq-P debug output. + + This option will slow down process creation somewhat. + config DEBUG_SLAB bool "Debug memory allocations" + depends on DEBUG_KERNEL + help + Say Y here to have the kernel do limited verification on memory + allocation as well as poisoning memory on free to catch use of freed + memory. config MAGIC_SYSRQ bool "Magic SysRq key" + depends on DEBUG_KERNEL help If you say Y here, you will have some control over the system even if the system crashes for example during kernel debugging (e.g., you @@ -398,22 +419,30 @@ config DEBUG_SPINLOCK bool "Spinlock debugging" + depends on DEBUG_KERNEL + help + Say Y here and build SMP to catch missing spinlock initialization + and certain other kinds of spinlock errors commonly made. This is + best used in conjunction with the NMI watchdog so that spinlock + deadlocks are also debuggable. config DEBUG_HIGHMEM bool "Highmem debugging" depends on DEBUG_KERNEL && HIGHMEM help - This options enables addition error checking for high memory systems. - Disable for production systems. + This options enables additional error checking for high memory + systems. Disable for production systems. config DEBUG_SPINLOCK_SLEEP bool "Sleep-inside-spinlock checking" + depends on DEBUG_KERNEL help If you say Y here, various routines which may sleep will become very noisy if they are called with a spinlock held. config DEBUG_BUGVERBOSE bool "Verbose BUG() reporting (adds 70K)" + depends on DEBUG_KERNEL help Say Y here to make BUG() panics output the file name and line number of the BUG call as well as the EIP and oops trace. This aids diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c --- a/arch/sparc/kernel/sparc_ksyms.c Sun Mar 7 18:39:36 2004 +++ b/arch/sparc/kernel/sparc_ksyms.c Sun Mar 7 18:39:36 2004 @@ -157,7 +157,6 @@ #ifdef CONFIG_SMP /* IRQ implementation. */ -EXPORT_SYMBOL(global_irq_holder); EXPORT_SYMBOL(synchronize_irq); /* Misc SMP information */ diff -Nru a/arch/sparc/kernel/trampoline.S b/arch/sparc/kernel/trampoline.S --- a/arch/sparc/kernel/trampoline.S Sun Mar 7 18:39:38 2004 +++ b/arch/sparc/kernel/trampoline.S Sun Mar 7 18:39:38 2004 @@ -13,6 +13,7 @@ #include #include #include +#include .globl sun4m_cpu_startup, __smp4m_processor_id .globl sun4d_cpu_startup, __smp4d_processor_id diff -Nru a/arch/sparc/mm/nosun4c.c b/arch/sparc/mm/nosun4c.c --- a/arch/sparc/mm/nosun4c.c Sun Mar 7 18:39:38 2004 +++ b/arch/sparc/mm/nosun4c.c Sun Mar 7 18:39:38 2004 @@ -57,6 +57,11 @@ return NULL; } +pte_t *sun4c_pte_offset_kernel(pmd_t *dir, unsigned long address) +{ + return NULL; +} + void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) { } diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c --- a/arch/sparc/mm/srmmu.c Sun Mar 7 18:39:37 2004 +++ b/arch/sparc/mm/srmmu.c Sun Mar 7 18:39:37 2004 @@ -627,8 +627,15 @@ */ struct thread_info *srmmu_alloc_thread_info(void) { - return (struct thread_info *) - __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER); + struct thread_info *ret; + + ret = (struct thread_info *)__get_free_pages(GFP_KERNEL, + THREAD_INFO_ORDER); +#ifdef CONFIG_DEBUG_STACK_USAGE + memset(ret, 0, PAGE_SIZE << THREAD_INFO_ORDER); +#endif /* DEBUG_STACK_USAGE */ + + return ret; } static void srmmu_free_thread_info(struct thread_info *ti) diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c --- a/arch/sparc/mm/sun4c.c Sun Mar 7 18:39:37 2004 +++ b/arch/sparc/mm/sun4c.c Sun Mar 7 18:39:37 2004 @@ -1058,6 +1058,11 @@ #ifndef CONFIG_SUN4 sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); #endif + +#ifdef CONFIG_DEBUG_STACK_USAGE + memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); +#endif /* DEBUG_STACK_USAGE */ + return (struct thread_info *) addr; } diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig --- a/arch/sparc64/defconfig Sun Mar 7 18:39:37 2004 +++ b/arch/sparc64/defconfig Sun Mar 7 18:39:37 2004 @@ -100,19 +100,19 @@ CONFIG_PRINTER=m CONFIG_ENVCTRL=m CONFIG_DISPLAY7SEG=m -CONFIG_WATCHDOG_CP1XXX=m -CONFIG_WATCHDOG_RIO=m # CONFIG_CMDLINE_BOOL is not set # # Generic Driver Options # CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set # # Graphics support # CONFIG_FB=y +# CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_BW2 is not set @@ -211,7 +211,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set -CONFIG_DCSSBLK=m # # ATA/ATAPI/MFM/RLL support @@ -407,6 +406,8 @@ # # CONFIG_IEEE1394_VERBOSEDEBUG is not set CONFIG_IEEE1394_OUI_DB=y +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y # # Device Drivers @@ -1638,6 +1639,8 @@ # Watchdog Device Drivers # CONFIG_SOFT_WATCHDOG=m +CONFIG_WATCHDOG_CP1XXX=m +CONFIG_WATCHDOG_RIO=m # # PCI-based Watchdog Cards @@ -1647,6 +1650,11 @@ CONFIG_WDT_501_PCI=y # +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m + +# # Profiling support # CONFIG_PROFILING=y @@ -1691,6 +1699,7 @@ CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_ARC4=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_TEST=m diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c --- a/arch/sparc64/kernel/ioctl32.c Sun Mar 7 18:39:38 2004 +++ b/arch/sparc64/kernel/ioctl32.c Sun Mar 7 18:39:38 2004 @@ -1117,34 +1117,6 @@ COMPATIBLE_IOCTL(BNEPCONNDEL) COMPATIBLE_IOCTL(BNEPGETCONNLIST) COMPATIBLE_IOCTL(BNEPGETCONNINFO) -/* device-mapper */ -#if defined(CONFIG_DM_IOCTL_V4) -COMPATIBLE_IOCTL(DM_VERSION) -COMPATIBLE_IOCTL(DM_REMOVE_ALL) -COMPATIBLE_IOCTL(DM_LIST_DEVICES) -COMPATIBLE_IOCTL(DM_DEV_CREATE) -COMPATIBLE_IOCTL(DM_DEV_REMOVE) -COMPATIBLE_IOCTL(DM_DEV_RENAME) -COMPATIBLE_IOCTL(DM_DEV_SUSPEND) -COMPATIBLE_IOCTL(DM_DEV_STATUS) -COMPATIBLE_IOCTL(DM_DEV_WAIT) -COMPATIBLE_IOCTL(DM_TABLE_LOAD) -COMPATIBLE_IOCTL(DM_TABLE_CLEAR) -COMPATIBLE_IOCTL(DM_TABLE_DEPS) -COMPATIBLE_IOCTL(DM_TABLE_STATUS) -#else -COMPATIBLE_IOCTL(DM_VERSION) -COMPATIBLE_IOCTL(DM_REMOVE_ALL) -COMPATIBLE_IOCTL(DM_DEV_CREATE) -COMPATIBLE_IOCTL(DM_DEV_REMOVE) -COMPATIBLE_IOCTL(DM_DEV_RELOAD) -COMPATIBLE_IOCTL(DM_DEV_SUSPEND) -COMPATIBLE_IOCTL(DM_DEV_RENAME) -COMPATIBLE_IOCTL(DM_DEV_DEPS) -COMPATIBLE_IOCTL(DM_DEV_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_WAIT) -#endif /* And these ioctls need translation */ /* NCPFS */ HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) diff -Nru a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c --- a/arch/x86_64/kernel/acpi/boot.c Sun Mar 7 18:39:36 2004 +++ b/arch/x86_64/kernel/acpi/boot.c Sun Mar 7 18:39:36 2004 @@ -48,11 +48,12 @@ #define PREFIX "ACPI: " -int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */ +int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ int acpi_ht __initdata = 1; /* enable HT */ int acpi_lapic; int acpi_ioapic; +int acpi_strict; /* -------------------------------------------------------------------------- Boot-time Configuration @@ -264,7 +265,7 @@ * programs the PIC-mode SCI to Level Trigger. * (NO-OP if the BIOS set Level Trigger already) * - * If a PIC-mode SCI is not recogznied or gives spurious IRQ7's + * If a PIC-mode SCI is not recognized or gives spurious IRQ7's * it may require Edge Trigger -- use "acpi_pic_sci=edge" * (NO-OP if the BIOS set Edge Trigger already) * diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c --- a/arch/x86_64/kernel/mpparse.c Sun Mar 7 18:39:37 2004 +++ b/arch/x86_64/kernel/mpparse.c Sun Mar 7 18:39:37 2004 @@ -996,7 +996,7 @@ continue; } if ((1< + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include +#include +#include + +#define ARC4_MIN_KEY_SIZE 1 +#define ARC4_MAX_KEY_SIZE 256 +#define ARC4_BLOCK_SIZE 1 + +struct arc4_ctx { + u8 S[256]; + u8 x, y; +}; + +static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags) +{ + struct arc4_ctx *ctx = ctx_arg; + int i, j = 0, k = 0; + + ctx->x = 1; + ctx->y = 0; + + for(i = 0; i < 256; i++) + ctx->S[i] = i; + + for(i = 0; i < 256; i++) + { + u8 a = ctx->S[i]; + j = (j + in_key[k] + a) & 0xff; + ctx->S[i] = ctx->S[j]; + ctx->S[j] = a; + if(++k >= key_len) + k = 0; + } + + /* TODO: dump the first 768 bytes generated as recommended + by Ilya Mironov (http://eprint.iacr.org/2002/067/) to + increase the statistical strength of the state table */ + + return 0; +} + +static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in) +{ + struct arc4_ctx *ctx = ctx_arg; + + u8 *const S = ctx->S; + u8 x = ctx->x; + u8 y = ctx->y; + u8 a, b; + + a = S[x]; + y = (y + a) & 0xff; + b = S[y]; + S[x] = b; + S[y] = a; + x = (x + 1) & 0xff; + *out++ = *in ^ S[(a + b) & 0xff]; + + ctx->x = x; + ctx->y = y; +} + +static struct crypto_alg arc4_alg = { + .cra_name = "arc4", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = ARC4_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct arc4_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), + .cra_u = { .cipher = { + .cia_min_keysize = ARC4_MIN_KEY_SIZE, + .cia_max_keysize = ARC4_MAX_KEY_SIZE, + .cia_setkey = arc4_set_key, + .cia_encrypt = arc4_crypt, + .cia_decrypt = arc4_crypt } } +}; + +static int __init arc4_init(void) +{ + return crypto_register_alg(&arc4_alg); +} + + +static void __exit arc4_exit(void) +{ + crypto_unregister_alg(&arc4_alg); +} + +module_init(arc4_init); +module_exit(arc4_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ARC4 Cipher Algorithm"); +MODULE_AUTHOR("Jon Oberheide "); diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c --- a/crypto/tcrypt.c Sun Mar 7 18:39:38 2004 +++ b/crypto/tcrypt.c Sun Mar 7 18:39:38 2004 @@ -61,7 +61,7 @@ static char *check[] = { "des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", - "deflate", NULL + "arc4", "deflate", NULL }; static void @@ -556,6 +556,10 @@ test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); + //ARC4 + test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); + test_cipher ("arc4x", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); + test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS); test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS); test_deflate(); @@ -636,6 +640,11 @@ case 15: test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS); test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS); + break; + + case 16: + test_cipher ("arc4", MODE_ECB, ENCRYPT, arc4_enc_tv_template, ARC4_ENC_TEST_VECTORS); + test_cipher ("arc4", MODE_ECB, DECRYPT, arc4_dec_tv_template, ARC4_DEC_TEST_VECTORS); break; #ifdef CONFIG_CRYPTO_HMAC diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h --- a/crypto/tcrypt.h Sun Mar 7 18:39:38 2004 +++ b/crypto/tcrypt.h Sun Mar 7 18:39:38 2004 @@ -1488,6 +1488,147 @@ }, }; +/* + * ARC4 test vectors from OpenSSL + */ +#define ARC4_ENC_TEST_VECTORS 7 +#define ARC4_DEC_TEST_VECTORS 7 + +struct cipher_testvec arc4_enc_tv_template[] = +{ + { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .ilen = 8, + .result = { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ilen = 8, + .result = { 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79 }, + .rlen = 8, + }, { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .klen = 8, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .ilen = 8, + .result = { 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a }, + .rlen = 8, + }, { + .key = { 0xef, 0x01, 0x23, 0x45}, + .klen = 4, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .ilen = 20, + .result = { 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61, 0x5a, 0x11, 0x62, 0xe1, 0xc7, 0xba, + 0x36, 0xb6, 0x78, 0x58 }, + .rlen = 20, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78 }, + .ilen = 28, + .result = { 0x66, 0xa0, 0x94, 0x9f, 0x8a, 0xf7, 0xd6, 0x89, + 0x1f, 0x7f, 0x83, 0x2b, 0xa8, 0x33, 0xc0, 0x0c, + 0x89, 0x2e, 0xbe, 0x30, 0x14, 0x3c, 0xe2, 0x87, + 0x40, 0x01, 0x1e, 0xcf }, + .rlen = 28, + }, { + .key = { 0xef, 0x01, 0x23, 0x45 }, + .klen = 4, + .input = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }, + .ilen = 10, + .result = { 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61 }, + .rlen = 10, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .klen = 16, + .input = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + .ilen = 8, + .result = { 0x69, 0x72, 0x36, 0x59, 0x1B, 0x52, 0x42, 0xB1 }, + .rlen = 8, + }, +}; + +struct cipher_testvec arc4_dec_tv_template[] = +{ + { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .rlen = 8, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79 }, + .ilen = 8, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .rlen = 8, + }, { + .key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .klen = 8, + .input = { 0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a }, + .ilen = 8, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .rlen = 8, + }, { + .key = { 0xef, 0x01, 0x23, 0x45}, + .klen = 4, + .input = { 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61, 0x5a, 0x11, 0x62, 0xe1, 0xc7, 0xba, + 0x36, 0xb6, 0x78, 0x58 }, + .ilen = 20, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + .rlen = 20, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, + .klen = 8, + .input = { 0x66, 0xa0, 0x94, 0x9f, 0x8a, 0xf7, 0xd6, 0x89, + 0x1f, 0x7f, 0x83, 0x2b, 0xa8, 0x33, 0xc0, 0x0c, + 0x89, 0x2e, 0xbe, 0x30, 0x14, 0x3c, 0xe2, 0x87, + 0x40, 0x01, 0x1e, 0xcf }, + .ilen = 28, + .result = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78 }, + .rlen = 28, + }, { + .key = { 0xef, 0x01, 0x23, 0x45 }, + .klen = 4, + .input = { 0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61 }, + .ilen = 10, + .result = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }, + .rlen = 10, + }, { + .key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .klen = 16, + .input = { 0x69, 0x72, 0x36, 0x59, 0x1B, 0x52, 0x42, 0xB1 }, + .ilen = 8, + .result = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + .rlen = 8, + }, +}; + + /* * Compression stuff. */ diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig --- a/drivers/acpi/Kconfig Sun Mar 7 18:39:38 2004 +++ b/drivers/acpi/Kconfig Sun Mar 7 18:39:38 2004 @@ -251,18 +251,6 @@ This driver will enable your system to shut down using ACPI, and dump your ACPI DSDT table using /proc/acpi/dsdt. -config ACPI_RELAXED_AML - bool "Relaxed AML" - depends on ACPI_INTERPRETER - depends on !IA64_SGI_SN - default n - help - If you say `Y' here, the ACPI interpreter will relax its checking - for valid AML and will ignore some AML mistakes, such as off-by-one - errors in region sizes. Some laptops may require this option. In - particular, many Toshiba laptops require this for correct operation - of the AC module. - config X86_PM_TIMER bool "Power Management Timer Support" depends on X86 && ACPI diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c --- a/drivers/acpi/executer/exfldio.c Sun Mar 7 18:39:37 2004 +++ b/drivers/acpi/executer/exfldio.c Sun Mar 7 18:39:37 2004 @@ -154,8 +154,7 @@ field_datum_byte_offset, obj_desc->common_field.access_byte_width, acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); - #ifdef CONFIG_ACPI_RELAXED_AML - { + if (!acpi_strict) { /* * Allow access to the field if it is within the region size * rounded up to a multiple of the access byte width. This @@ -186,9 +185,9 @@ return_ACPI_STATUS (AE_OK); } } - #else + else { return_ACPI_STATUS (AE_AML_REGION_LIMIT); - #endif + } } return_ACPI_STATUS (AE_OK); diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c --- a/drivers/acpi/hardware/hwgpe.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/hardware/hwgpe.c Sun Mar 7 18:39:36 2004 @@ -528,6 +528,14 @@ /* Examine each GPE register within the block */ for (i = 0; i < gpe_block->register_count; i++) { + /* Clear the entire status register */ + + status = acpi_hw_low_level_write (8, 0xFF, + &gpe_block->register_info[i].status_address); + if (ACPI_FAILURE (status)) { + return (status); + } + /* * We previously stored the enabled status of all GPEs. * Blast them back in. diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c --- a/drivers/acpi/hardware/hwregs.c Sun Mar 7 18:39:38 2004 +++ b/drivers/acpi/hardware/hwregs.c Sun Mar 7 18:39:38 2004 @@ -152,11 +152,11 @@ /* * Evaluate the namespace object containing the values for this state */ - status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_db_sleep_states[sleep_state], + status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state], NULL, &obj_desc); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n", - acpi_format_exception (status), acpi_gbl_db_sleep_states[sleep_state])); + acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state])); return_ACPI_STATUS (status); } @@ -201,7 +201,7 @@ if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n", - acpi_gbl_db_sleep_states[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc))); + acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc))); } acpi_ut_remove_reference (obj_desc); diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/hardware/hwsleep.c Sun Mar 7 18:39:36 2004 @@ -48,6 +48,19 @@ ACPI_MODULE_NAME ("hwsleep") +#define METHOD_NAME__BFS "\\_BFS" +#define METHOD_NAME__GTS "\\_GTS" +#define METHOD_NAME__PTS "\\_PTS" +#define METHOD_NAME__SST "\\_SI._SST" +#define METHOD_NAME__WAK "\\_WAK" + +#define ACPI_SST_INDICATOR_OFF 0 +#define ACPI_SST_WORKING 1 +#define ACPI_SST_WAKING 2 +#define ACPI_SST_SLEEPING 3 +#define ACPI_SST_SLEEP_CONTEXT 4 + + /****************************************************************************** * * FUNCTION: acpi_set_firmware_waking_vector @@ -171,19 +184,41 @@ /* Run the _PTS and _GTS methods */ - status = acpi_evaluate_object (NULL, "\\_PTS", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { return_ACPI_STATUS (status); } - status = acpi_evaluate_object (NULL, "\\_GTS", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { return_ACPI_STATUS (status); } + /* Setup the argument to _SST */ + + switch (sleep_state) { + case ACPI_STATE_S0: + arg.integer.value = ACPI_SST_WORKING; + break; + + case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + arg.integer.value = ACPI_SST_SLEEPING; + break; + + case ACPI_STATE_S4: + arg.integer.value = ACPI_SST_SLEEP_CONTEXT; + break; + + default: + arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */ + break; + } + /* Set the system indicators to show the desired sleep state. */ - status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); } @@ -477,19 +512,19 @@ /* Ignore any errors from these methods */ - arg.integer.value = 0; - status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + arg.integer.value = ACPI_SST_WAKING; + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); } arg.integer.value = sleep_state; - status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); } - status = acpi_evaluate_object (NULL, "\\_WAK", &arg_list, NULL); + status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status))); } @@ -501,8 +536,25 @@ return_ACPI_STATUS (status); } + /* Enable power button */ + + acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id, + 1, ACPI_MTX_DO_NOT_LOCK); + acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id, + 1, ACPI_MTX_DO_NOT_LOCK); + /* Enable BM arbitration */ status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + + arg.integer.value = ACPI_SST_WORKING; + status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c --- a/drivers/acpi/namespace/nseval.c Sun Mar 7 18:39:37 2004 +++ b/drivers/acpi/namespace/nseval.c Sun Mar 7 18:39:37 2004 @@ -110,7 +110,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } prefix_node = acpi_ns_map_handle_to_node (handle); @@ -197,7 +197,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } /* Lookup the name in the namespace */ diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c --- a/drivers/acpi/namespace/nsutils.c Sun Mar 7 18:39:37 2004 +++ b/drivers/acpi/namespace/nsutils.c Sun Mar 7 18:39:37 2004 @@ -918,7 +918,7 @@ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + goto cleanup; } /* Setup lookup scope (search starting point) */ @@ -936,10 +936,10 @@ internal_path, acpi_format_exception (status))); } - /* Cleanup */ - (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); +cleanup: + /* Cleanup */ if (internal_path) { ACPI_MEM_FREE (internal_path); } diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c --- a/drivers/acpi/namespace/nsxfname.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/namespace/nsxfname.c Sun Mar 7 18:39:36 2004 @@ -326,6 +326,13 @@ info.valid |= ACPI_VALID_ADR; } + /* Execute the Device._sx_d methods */ + + status = acpi_ut_execute_sxds (node, info.highest_dstates); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_STA; + } + status = AE_OK; } diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c --- a/drivers/acpi/pci_link.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/pci_link.c Sun Mar 7 18:39:36 2004 @@ -768,7 +768,6 @@ static int __init acpi_irq_nobalance_set(char *str) { -printk("ACPI STATIC SET\n"); acpi_irq_balance = 0; return(1); } @@ -776,7 +775,6 @@ int __init acpi_irq_balance_set(char *str) { -printk("ACPI BALANCE SET\n"); acpi_irq_balance = 1; return(1); } diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c --- a/drivers/acpi/resources/rsxface.c Sun Mar 7 18:39:37 2004 +++ b/drivers/acpi/resources/rsxface.c Sun Mar 7 18:39:37 2004 @@ -239,6 +239,7 @@ acpi_status status; struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; struct acpi_resource *resource; + struct acpi_resource *buffer_end; ACPI_FUNCTION_TRACE ("acpi_walk_resources"); @@ -255,7 +256,13 @@ return_ACPI_STATUS (status); } - resource = (struct acpi_resource *) buffer.pointer; + /* Setup pointers */ + + resource = (struct acpi_resource *) buffer.pointer; + buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length); + + /* Walk the resource list */ + for (;;) { if (!resource || resource->id == ACPI_RSTYPE_END_TAG) { break; @@ -268,6 +275,7 @@ case AE_CTRL_DEPTH: /* Just keep going */ + status = AE_OK; break; @@ -285,7 +293,15 @@ goto cleanup; } + /* Get the next resource descriptor */ + resource = ACPI_NEXT_RESOURCE (resource); + + /* Check for end-of-buffer */ + + if (resource >= buffer_end) { + goto cleanup; + } } cleanup: diff -Nru a/drivers/acpi/tables.c b/drivers/acpi/tables.c --- a/drivers/acpi/tables.c Sun Mar 7 18:39:37 2004 +++ b/drivers/acpi/tables.c Sun Mar 7 18:39:37 2004 @@ -58,6 +58,7 @@ [ACPI_SSDT] = "SSDT", [ACPI_SPMI] = "SPMI", [ACPI_HPET] = "HPET", + [ACPI_MCFG] = "MCFG", }; static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" }; @@ -550,6 +551,14 @@ return 0; } +/* + * acpi_table_init() + * + * find RSDP, find and checksum SDT/XSDT. + * checksum all tables, print SDT/XSDT + * + * result: sdt_entry[] is initialized + */ int __init acpi_table_init (void) diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c --- a/drivers/acpi/utilities/uteval.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/utilities/uteval.c Sun Mar 7 18:39:36 2004 @@ -562,3 +562,63 @@ acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); } + + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_Sxds + * + * PARAMETERS: device_node - Node for the device + * *Flags - Where the status flags are returned + * + * RETURN: Status + * + * DESCRIPTION: Executes _STA for selected device and stores results in + * *Flags. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_sxds ( + struct acpi_namespace_node *device_node, + u8 *highest) +{ + union acpi_operand_object *obj_desc; + acpi_status status; + u32 i; + + + ACPI_FUNCTION_TRACE ("ut_execute_Sxds"); + + + for (i = 0; i < 4; i++) { + highest[i] = 0xFF; + status = acpi_ut_evaluate_object (device_node, + (char *) acpi_gbl_highest_dstate_names[i], + ACPI_BTYPE_INTEGER, &obj_desc); + if (ACPI_FAILURE (status)) { + if (status != AE_NOT_FOUND) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "%s on Device %4.4s, %s\n", + (char *) acpi_gbl_highest_dstate_names[i], + acpi_ut_get_node_name (device_node), + acpi_format_exception (status))); + + return_ACPI_STATUS (status); + } + } + else { + /* Extract the Dstate value */ + + highest[i] = (u8) obj_desc->integer.value; + + /* Delete the return object */ + + acpi_ut_remove_reference (obj_desc); + } + } + + return_ACPI_STATUS (AE_OK); +} diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Sun Mar 7 18:39:36 2004 +++ b/drivers/acpi/utilities/utglobal.c Sun Mar 7 18:39:36 2004 @@ -171,7 +171,7 @@ const u8 acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128}; -const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT] = { +const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { "\\_S0_", "\\_S1_", "\\_S2_", @@ -179,6 +179,11 @@ "\\_S4_", "\\_S5_"}; +const char *acpi_gbl_highest_dstate_names[4] = { + "_S1D", + "_S2D", + "_S3D", + "_S4D"}; /****************************************************************************** * diff -Nru a/drivers/block/Kconfig b/drivers/block/Kconfig --- a/drivers/block/Kconfig Sun Mar 7 18:39:36 2004 +++ b/drivers/block/Kconfig Sun Mar 7 18:39:36 2004 @@ -321,6 +321,7 @@ config BLK_DEV_INITRD bool "Initial RAM disk (initrd) support" + depends on BLK_DEV_RAM && BLK_DEV_RAM!=m help The initial RAM disk is a RAM disk that is loaded by the boot loader (loadlin or lilo) and that is mounted as root before the normal boot diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c --- a/drivers/block/floppy.c Sun Mar 7 18:39:36 2004 +++ b/drivers/block/floppy.c Sun Mar 7 18:39:36 2004 @@ -4242,6 +4242,15 @@ disks[i] = alloc_disk(1); if (!disks[i]) goto Enomem; + + disks[i]->major = FLOPPY_MAJOR; + disks[i]->first_minor = TOMINOR(i); + disks[i]->fops = &floppy_fops; + sprintf(disks[i]->disk_name, "fd%d", i); + + init_timer(&motor_off_timer[i]); + motor_off_timer[i].data = i; + motor_off_timer[i].function = motor_off_callback; } devfs_mk_dir ("floppy"); @@ -4255,13 +4264,6 @@ goto fail_queue; } - for (i=0; imajor = FLOPPY_MAJOR; - disks[i]->first_minor = TOMINOR(i); - disks[i]->fops = &floppy_fops; - sprintf(disks[i]->disk_name, "fd%d", i); - } - blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE, floppy_find, NULL, NULL); @@ -4366,9 +4368,6 @@ } for (drive = 0; drive < N_DRIVE; drive++) { - init_timer(&motor_off_timer[drive]); - motor_off_timer[drive].data = drive; - motor_off_timer[drive].function = motor_off_callback; if (!(allowed_drive_mask & (1 << drive))) continue; if (fdc_state[FDC(drive)].version == FDC_NONE) diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c --- a/drivers/block/rd.c Sun Mar 7 18:39:37 2004 +++ b/drivers/block/rd.c Sun Mar 7 18:39:37 2004 @@ -316,6 +316,7 @@ } del_gendisk(rd_disks[i]); put_disk(rd_disks[i]); + blk_cleanup_queue(rd_queue[i]); } devfs_remove("rd"); unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); @@ -379,8 +380,10 @@ out_queue: unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); out: - while (i--) + while (i--) { put_disk(rd_disks[i]); + blk_cleanup_queue(rd_queue[i]); + } return err; } diff -Nru a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c --- a/drivers/bluetooth/hci_usb.c Sun Mar 7 18:39:38 2004 +++ b/drivers/bluetooth/hci_usb.c Sun Mar 7 18:39:38 2004 @@ -31,7 +31,7 @@ * * $Id: hci_usb.c,v 1.8 2002/07/18 17:23:09 maxk Exp $ */ -#define VERSION "2.4" +#define VERSION "2.5" #include #include @@ -70,12 +70,6 @@ static struct usb_driver hci_usb_driver; static struct usb_device_id bluetooth_ids[] = { - /* Broadcom BCM2033 without firmware */ - { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, - - /* Digianswer device */ - { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, - /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) }, @@ -93,6 +87,19 @@ MODULE_DEVICE_TABLE (usb, bluetooth_ids); +static struct usb_device_id blacklist_ids[] = { + /* Broadcom BCM2033 without firmware */ + { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, + + /* Broadcom BCM2035 */ + { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET }, + + /* Digianswer device */ + { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, + + { } /* Terminating entry */ +}; + struct _urb *_urb_alloc(int isoc, int gfp) { struct _urb *_urb = kmalloc(sizeof(struct _urb) + @@ -644,7 +651,7 @@ #endif } BT_DBG("new packet len %d", len); - + skb = bt_skb_alloc(len, GFP_ATOMIC); if (!skb) { BT_ERR("%s no memory for the packet", husb->hdev->name); @@ -790,6 +797,13 @@ BT_DBG("udev %p ifnum %d", udev, ifnum); + if (!id->driver_info) { + const struct usb_device_id *match; + match = usb_match_id(intf, blacklist_ids); + if (match) + id = match; + } + iface = udev->actconfig->interface[0]; if (id->driver_info & HCI_IGNORE) @@ -928,6 +942,9 @@ hdev->owner = THIS_MODULE; + if (id->driver_info & HCI_RESET) + set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); + if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); hci_free_dev(hdev); @@ -994,6 +1011,6 @@ module_init(hci_usb_init); module_exit(hci_usb_cleanup); -MODULE_AUTHOR("Maxim Krasnyansky "); +MODULE_AUTHOR("Maxim Krasnyansky , Marcel Holtmann "); MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION); MODULE_LICENSE("GPL"); diff -Nru a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h --- a/drivers/bluetooth/hci_usb.h Sun Mar 7 18:39:38 2004 +++ b/drivers/bluetooth/hci_usb.h Sun Mar 7 18:39:38 2004 @@ -38,7 +38,8 @@ #define HCI_DIGI_REQ 0x40 #define HCI_IGNORE 0x01 -#define HCI_DIGIANSWER 0x02 +#define HCI_RESET 0x02 +#define HCI_DIGIANSWER 0x04 #define HCI_MAX_IFACE_NUM 3 diff -Nru a/drivers/cdrom/Makefile b/drivers/cdrom/Makefile --- a/drivers/cdrom/Makefile Sun Mar 7 18:39:37 2004 +++ b/drivers/cdrom/Makefile Sun Mar 7 18:39:37 2004 @@ -20,3 +20,4 @@ obj-$(CONFIG_SBPCD) += sbpcd.o cdrom.o obj-$(CONFIG_SJCD) += sjcd.o obj-$(CONFIG_CDU535) += sonycd535.o +obj-$(CONFIG_VIOCD) += viocd.o cdrom.o diff -Nru a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/cdrom/viocd.c Sun Mar 7 18:39:38 2004 @@ -0,0 +1,656 @@ +/* -*- linux-c -*- + * drivers/cdrom/viocd.c + * + * iSeries Virtual CD Rom + * + * Authors: Dave Boutcher + * Ryan Arnold + * Colin Devilbiss + * Stephen Rothwell + * + * (C) Copyright 2000-2004 IBM Corporation + * + * 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) anyu 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 + * + * This routine provides access to CD ROM drives owned and managed by an + * OS/400 partition running on the same box as this Linux partition. + * + * All operations are performed by sending messages back and forth to + * the OS/400 partition. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define VIOCD_DEVICE "iseries/vcd" +#define VIOCD_DEVICE_DEVFS "iseries/vcd" + +#define VIOCD_VERS "1.06" + +#define VIOCD_KERN_WARNING KERN_WARNING "viocd: " +#define VIOCD_KERN_INFO KERN_INFO "viocd: " + +struct viocdlpevent { + struct HvLpEvent event; + u32 reserved; + u16 version; + u16 sub_result; + u16 disk; + u16 flags; + u32 token; + u64 offset; /* On open, max number of disks */ + u64 len; /* On open, size of the disk */ + u32 block_size; /* Only set on open */ + u32 media_size; /* Only set on open */ +}; + +enum viocdsubtype { + viocdopen = 0x0001, + viocdclose = 0x0002, + viocdread = 0x0003, + viocdwrite = 0x0004, + viocdlockdoor = 0x0005, + viocdgetinfo = 0x0006, + viocdcheck = 0x0007 +}; + +/* + * Should probably make this a module parameter....sigh + */ +#define VIOCD_MAX_CD 8 + +static const struct vio_error_entry viocd_err_table[] = { + {0x0201, EINVAL, "Invalid Range"}, + {0x0202, EINVAL, "Invalid Token"}, + {0x0203, EIO, "DMA Error"}, + {0x0204, EIO, "Use Error"}, + {0x0205, EIO, "Release Error"}, + {0x0206, EINVAL, "Invalid CD"}, + {0x020C, EROFS, "Read Only Device"}, + {0x020D, ENOMEDIUM, "Changed or Missing Volume (or Varied Off?)"}, + {0x020E, EIO, "Optical System Error (Varied Off?)"}, + {0x02FF, EIO, "Internal Error"}, + {0x3010, EIO, "Changed Volume"}, + {0xC100, EIO, "Optical System Error"}, + {0x0000, 0, NULL}, +}; + +/* + * This is the structure we use to exchange info between driver and interrupt + * handler + */ +struct viocd_waitevent { + struct completion com; + int rc; + u16 sub_result; + int changed; +}; + +/* this is a lookup table for the true capabilities of a device */ +struct capability_entry { + char *type; + int capability; +}; + +static struct capability_entry capability_table[] __initdata = { + { "6330", CDC_LOCK | CDC_DVD_RAM }, + { "6321", CDC_LOCK }, + { "632B", 0 }, + { NULL , CDC_LOCK }, +}; + +/* These are our internal structures for keeping track of devices */ +static int viocd_numdev; + +struct cdrom_info { + char rsrcname[10]; + char type[4]; + char model[3]; +}; +static struct cdrom_info viocd_unitinfo[VIOCD_MAX_CD]; + +struct disk_info { + struct gendisk *viocd_disk; + struct cdrom_device_info viocd_info; +}; +static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; + +#define DEVICE_NR(di) ((di) - &viocd_diskinfo[0]) +#define VIOCDI viocd_diskinfo[deviceno].viocd_info + +static request_queue_t *viocd_queue; +static spinlock_t viocd_reqlock; + +#define MAX_CD_REQ 1 + +static int viocd_blk_open(struct inode *inode, struct file *file) +{ + struct disk_info *di = inode->i_bdev->bd_disk->private_data; + return cdrom_open(&di->viocd_info, inode, file); +} + +static int viocd_blk_release(struct inode *inode, struct file *file) +{ + struct disk_info *di = inode->i_bdev->bd_disk->private_data; + return cdrom_release(&di->viocd_info, file); +} + +static int viocd_blk_ioctl(struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg) +{ + struct disk_info *di = inode->i_bdev->bd_disk->private_data; + return cdrom_ioctl(&di->viocd_info, inode, cmd, arg); +} + +static int viocd_blk_media_changed(struct gendisk *disk) +{ + struct disk_info *di = disk->private_data; + return cdrom_media_changed(&di->viocd_info); +} + +struct block_device_operations viocd_fops = { + .owner = THIS_MODULE, + .open = viocd_blk_open, + .release = viocd_blk_release, + .ioctl = viocd_blk_ioctl, + .media_changed = viocd_blk_media_changed, +}; + +/* Get info on CD devices from OS/400 */ +static void __init get_viocd_info(void) +{ + dma_addr_t dmaaddr; + HvLpEvent_Rc hvrc; + int i; + struct viocd_waitevent we; + + dmaaddr = dma_map_single(iSeries_vio_dev, viocd_unitinfo, + sizeof(viocd_unitinfo), DMA_FROM_DEVICE); + if (dmaaddr == (dma_addr_t)-1) { + printk(VIOCD_KERN_WARNING "error allocating tce\n"); + return; + } + + init_completion(&we.com); + + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdgetinfo, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)&we, VIOVERSION << 16, dmaaddr, 0, + sizeof(viocd_unitinfo), 0); + if (hvrc != HvLpEvent_Rc_Good) { + printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n", + (int)hvrc); + return; + } + + wait_for_completion(&we.com); + + dma_unmap_single(iSeries_vio_dev, dmaaddr, sizeof(viocd_unitinfo), + DMA_FROM_DEVICE); + + if (we.rc) { + const struct vio_error_entry *err = + vio_lookup_rc(viocd_err_table, we.sub_result); + printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n", + we.rc, we.sub_result, err->msg); + return; + } + + for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) + viocd_numdev++; +} + +static int viocd_open(struct cdrom_device_info *cdi, int purpose) +{ + struct disk_info *diskinfo = cdi->handle; + int device_no = DEVICE_NR(diskinfo); + HvLpEvent_Rc hvrc; + struct viocd_waitevent we; + + init_completion(&we.com); + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdopen, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)&we, VIOVERSION << 16, ((u64)device_no << 48), + 0, 0, 0); + if (hvrc != 0) { + printk(VIOCD_KERN_WARNING + "bad rc on HvCallEvent_signalLpEventFast %d\n", + (int)hvrc); + return -EIO; + } + + wait_for_completion(&we.com); + + if (we.rc) { + const struct vio_error_entry *err = + vio_lookup_rc(viocd_err_table, we.sub_result); + printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on open: %s\n", + we.rc, we.sub_result, err->msg); + return -err->errno; + } + + return 0; +} + +static void viocd_release(struct cdrom_device_info *cdi) +{ + int device_no = DEVICE_NR((struct disk_info *)cdi->handle); + HvLpEvent_Rc hvrc; + + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdclose, + HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), 0, + VIOVERSION << 16, ((u64)device_no << 48), 0, 0, 0); + if (hvrc != 0) + printk(VIOCD_KERN_WARNING + "bad rc on HvCallEvent_signalLpEventFast %d\n", + (int)hvrc); +} + +/* Send a read or write request to OS/400 */ +static int send_request(struct request *req) +{ + HvLpEvent_Rc hvrc; + struct disk_info *diskinfo = req->rq_disk->private_data; + u64 len; + dma_addr_t dmaaddr; + struct scatterlist sg; + + BUG_ON(req->nr_phys_segments > 1); + BUG_ON(rq_data_dir(req) != READ); + + if (blk_rq_map_sg(req->q, req, &sg) == 0) { + printk(VIOCD_KERN_WARNING + "error setting up scatter/gather list\n"); + return -1; + } + + if (dma_map_sg(iSeries_vio_dev, &sg, 1, DMA_FROM_DEVICE) == 0) { + printk(VIOCD_KERN_WARNING "error allocating sg tce\n"); + return -1; + } + dmaaddr = sg_dma_address(&sg); + len = sg_dma_len(&sg); + if (dmaaddr == (dma_addr_t)-1) { + printk(VIOCD_KERN_WARNING "error allocating tce\n"); + return -1; + } + + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdread, + HvLpEvent_AckInd_DoAck, + HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)req, VIOVERSION << 16, + ((u64)DEVICE_NR(diskinfo) << 48) | dmaaddr, + (u64)req->sector * 512, len, 0); + if (hvrc != HvLpEvent_Rc_Good) { + printk(VIOCD_KERN_WARNING "hv error on op %d\n", (int)hvrc); + return -1; + } + + return 0; +} + + +static int rwreq; + +static void do_viocd_request(request_queue_t *q) +{ + struct request *req; + + while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) { + /* check for any kind of error */ + if (send_request(req) < 0) { + printk(VIOCD_KERN_WARNING + "unable to send message to OS/400!"); + end_request(req, 0); + } else + rwreq++; + } +} + +static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr) +{ + struct viocd_waitevent we; + HvLpEvent_Rc hvrc; + int device_no = DEVICE_NR((struct disk_info *)cdi->handle); + + init_completion(&we.com); + + /* Send the open event to OS/400 */ + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdcheck, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)&we, VIOVERSION << 16, ((u64)device_no << 48), + 0, 0, 0); + if (hvrc != 0) { + printk(VIOCD_KERN_WARNING "bad rc on HvCallEvent_signalLpEventFast %d\n", + (int)hvrc); + return -EIO; + } + + wait_for_completion(&we.com); + + /* Check the return code. If bad, assume no change */ + if (we.rc) { + const struct vio_error_entry *err = + vio_lookup_rc(viocd_err_table, we.sub_result); + printk(VIOCD_KERN_WARNING + "bad rc %d:0x%04X on check_change: %s; Assuming no change\n", + we.rc, we.sub_result, err->msg); + return 0; + } + + return we.changed; +} + +static int viocd_lock_door(struct cdrom_device_info *cdi, int locking) +{ + HvLpEvent_Rc hvrc; + u64 device_no = DEVICE_NR((struct disk_info *)cdi->handle); + /* NOTE: flags is 1 or 0 so it won't overwrite the device_no */ + u64 flags = !!locking; + struct viocd_waitevent we; + + init_completion(&we.com); + + /* Send the lockdoor event to OS/400 */ + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdlockdoor, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)&we, VIOVERSION << 16, + (device_no << 48) | (flags << 32), 0, 0, 0); + if (hvrc != 0) { + printk(VIOCD_KERN_WARNING "bad rc on HvCallEvent_signalLpEventFast %d\n", + (int)hvrc); + return -EIO; + } + + wait_for_completion(&we.com); + + if (we.rc != 0) + return -EIO; + return 0; +} + +/* This routine handles incoming CD LP events */ +static void vio_handle_cd_event(struct HvLpEvent *event) +{ + struct viocdlpevent *bevent; + struct viocd_waitevent *pwe; + struct disk_info *di; + unsigned long flags; + struct request *req; + + + if (event == NULL) + /* Notification that a partition went away! */ + return; + /* First, we should NEVER get an int here...only acks */ + if (event->xFlags.xFunction == HvLpEvent_Function_Int) { + printk(VIOCD_KERN_WARNING + "Yikes! got an int in viocd event handler!\n"); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } + + bevent = (struct viocdlpevent *)event; + + switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) { + case viocdopen: + if (event->xRc == 0) { + di = &viocd_diskinfo[bevent->disk]; + blk_queue_hardsect_size(viocd_queue, + bevent->block_size); + set_capacity(di->viocd_disk, + bevent->media_size * + bevent->block_size / 512); + } + /* FALLTHROUGH !! */ + case viocdgetinfo: + case viocdlockdoor: + pwe = (struct viocd_waitevent *)event->xCorrelationToken; +return_complete: + pwe->rc = event->xRc; + pwe->sub_result = bevent->sub_result; + complete(&pwe->com); + break; + + case viocdcheck: + pwe = (struct viocd_waitevent *)event->xCorrelationToken; + pwe->changed = bevent->flags; + goto return_complete; + + case viocdclose: + break; + + case viocdread: + /* + * Since this is running in interrupt mode, we need to + * make sure we're not stepping on any global I/O operations + */ + spin_lock_irqsave(&viocd_reqlock, flags); + dma_unmap_single(iSeries_vio_dev, bevent->token, bevent->len, + DMA_FROM_DEVICE); + req = (struct request *)bevent->event.xCorrelationToken; + rwreq--; + + if (event->xRc != HvLpEvent_Rc_Good) { + const struct vio_error_entry *err = + vio_lookup_rc(viocd_err_table, + bevent->sub_result); + printk(VIOCD_KERN_WARNING "request %p failed " + "with rc %d:0x%04X: %s\n", + req, event->xRc, + bevent->sub_result, err->msg); + end_request(req, 0); + } else + end_request(req, 1); + + /* restart handling of incoming requests */ + spin_unlock_irqrestore(&viocd_reqlock, flags); + blk_run_queue(viocd_queue); + break; + + default: + printk(VIOCD_KERN_WARNING + "message with invalid subtype %0x04X!\n", + event->xSubtype & VIOMINOR_SUBTYPE_MASK); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } +} + +static struct cdrom_device_ops viocd_dops = { + .open = viocd_open, + .release = viocd_release, + .media_changed = viocd_media_changed, + .lock_door = viocd_lock_door, + .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM +}; + +static int __init find_capability(const char *type) +{ + struct capability_entry *entry; + + for(entry = capability_table; entry->type; ++entry) + if(!strncmp(entry->type, type, 4)) + break; + return entry->capability; +} + +static int __init viocd_init(void) +{ + struct gendisk *gendisk; + int deviceno; + int ret = 0; + + if (viopath_hostLp == HvLpIndexInvalid) { + vio_set_hostlp(); + /* If we don't have a host, bail out */ + if (viopath_hostLp == HvLpIndexInvalid) + return -ENODEV; + } + + printk(VIOCD_KERN_INFO "vers " VIOCD_VERS ", hosting partition %d\n", + viopath_hostLp); + + if (register_blkdev(VIOCD_MAJOR, VIOCD_DEVICE) != 0) { + printk(VIOCD_KERN_WARNING + "Unable to get major %d for %s\n", + VIOCD_MAJOR, VIOCD_DEVICE); + return -EIO; + } + + ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, + MAX_CD_REQ + 2); + if (ret) { + printk(VIOCD_KERN_WARNING + "error opening path to host partition %d\n", + viopath_hostLp); + goto out_unregister; + } + + /* Initialize our request handler */ + vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); + + get_viocd_info(); + if (viocd_numdev == 0) + goto out_undo_vio; + + ret = -ENOMEM; + spin_lock_init(&viocd_reqlock); + viocd_queue = blk_init_queue(do_viocd_request, &viocd_reqlock); + if (viocd_queue == NULL) + goto out_unregister; + blk_queue_max_hw_segments(viocd_queue, 1); + blk_queue_max_phys_segments(viocd_queue, 1); + blk_queue_max_sectors(viocd_queue, 4096 / 512); + + /* initialize units */ + for (deviceno = 0; deviceno < viocd_numdev; deviceno++) { + struct disk_info *d = &viocd_diskinfo[deviceno]; + struct cdrom_device_info *c = &d->viocd_info; + struct cdrom_info *ci = &viocd_unitinfo[deviceno]; + + c->ops = &viocd_dops; + c->speed = 4; + c->capacity = 1; + c->handle = d; + c->mask = ~find_capability(ci->type); + sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); + + if (register_cdrom(c) != 0) { + printk(VIOCD_KERN_WARNING + "Cannot register viocd CD-ROM %s!\n", + c->name); + continue; + } + printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " + "type %4.4s, model %3.3s\n", + c->name, ci->rsrcname, ci->type, ci->model); + gendisk = alloc_disk(1); + if (gendisk == NULL) { + printk(VIOCD_KERN_WARNING + "Cannot create gendisk for %s!\n", + c->name); + unregister_cdrom(&VIOCDI); + continue; + } + gendisk->major = VIOCD_MAJOR; + gendisk->first_minor = deviceno; + strncpy(gendisk->disk_name, c->name, + sizeof(gendisk->disk_name)); + snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name), + VIOCD_DEVICE_DEVFS "%d", deviceno); + gendisk->queue = viocd_queue; + gendisk->fops = &viocd_fops; + gendisk->flags = GENHD_FL_CD; + set_capacity(gendisk, 0); + gendisk->private_data = d; + d->viocd_disk = gendisk; + add_disk(gendisk); + } + + return 0; + +out_undo_vio: + vio_clearHandler(viomajorsubtype_cdio); + viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); +out_unregister: + unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); + return ret; +} + +static void __exit viocd_exit(void) +{ + int deviceno; + + for (deviceno = 0; deviceno < viocd_numdev; deviceno++) { + struct disk_info *d = &viocd_diskinfo[deviceno]; + if (unregister_cdrom(&d->viocd_info) != 0) + printk(VIOCD_KERN_WARNING + "Cannot unregister viocd CD-ROM %s!\n", + d->viocd_info.name); + del_gendisk(d->viocd_disk); + put_disk(d->viocd_disk); + } + blk_cleanup_queue(viocd_queue); + + viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); + vio_clearHandler(viomajorsubtype_cdio); + unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); +} + +module_init(viocd_init); +module_exit(viocd_exit); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c --- a/drivers/char/rio/rioctrl.c Sun Mar 7 18:39:37 2004 +++ b/drivers/char/rio/rioctrl.c Sun Mar 7 18:39:37 2004 @@ -522,7 +522,7 @@ else { rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n", (int) arg); - return 1; + return -ENOMEM; } return 0; } @@ -1593,12 +1593,12 @@ case RIO_NO_MESG: if ( su ) p->RIONoMessage = 1; - return su ? 0 : EPERM; + return su ? 0 : -EPERM; case RIO_MESG: if ( su ) p->RIONoMessage = 0; - return su ? 0 : EPERM; + return su ? 0 : -EPERM; case RIO_WHAT_MESG: if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, diff -Nru a/drivers/i2c/busses/i2c-elv.c b/drivers/i2c/busses/i2c-elv.c --- a/drivers/i2c/busses/i2c-elv.c Sun Mar 7 18:39:38 2004 +++ b/drivers/i2c/busses/i2c-elv.c Sun Mar 7 18:39:38 2004 @@ -152,7 +152,7 @@ return -ENODEV; } } - pr_debug("i2c-elv: found device at %#x.\n",base); + pr_debug("i2c-elv: found device at %#lx.\n",base); return 0; } diff -Nru a/drivers/i2c/busses/i2c-velleman.c b/drivers/i2c/busses/i2c-velleman.c --- a/drivers/i2c/busses/i2c-velleman.c Sun Mar 7 18:39:38 2004 +++ b/drivers/i2c/busses/i2c-velleman.c Sun Mar 7 18:39:38 2004 @@ -138,7 +138,7 @@ return -ENODEV; } } - pr_debug("i2c-velleman: found device at %#x.\n",base); + pr_debug("i2c-velleman: found device at %#lx.\n",base); return 0; } diff -Nru a/drivers/md/Kconfig b/drivers/md/Kconfig --- a/drivers/md/Kconfig Sun Mar 7 18:39:36 2004 +++ b/drivers/md/Kconfig Sun Mar 7 18:39:36 2004 @@ -162,14 +162,6 @@ If unsure, say N. -config DM_IOCTL_V4 - bool "ioctl interface version 4" - depends on BLK_DEV_DM - default y - ---help--- - Recent tools use a new version of the ioctl interface, only - select this option if you intend using such tools. - config DM_CRYPT tristate "Crypt target support" depends on BLK_DEV_DM && EXPERIMENTAL diff -Nru a/drivers/md/dm-ioctl-v1.c b/drivers/md/dm-ioctl-v1.c --- a/drivers/md/dm-ioctl-v1.c Sun Mar 7 18:39:38 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1159 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. - * - * This file is released under the GPL. - */ - -#include "dm.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DM_DRIVER_EMAIL "dm@uk.sistina.com" - -/*----------------------------------------------------------------- - * The ioctl interface needs to be able to look up devices by - * name or uuid. - *---------------------------------------------------------------*/ -struct hash_cell { - struct list_head name_list; - struct list_head uuid_list; - - char *name; - char *uuid; - struct mapped_device *md; -}; - -#define NUM_BUCKETS 64 -#define MASK_BUCKETS (NUM_BUCKETS - 1) -static struct list_head _name_buckets[NUM_BUCKETS]; -static struct list_head _uuid_buckets[NUM_BUCKETS]; - -void dm_hash_remove_all(void); - -/* - * Guards access to all three tables. - */ -static DECLARE_RWSEM(_hash_lock); - -static void init_buckets(struct list_head *buckets) -{ - unsigned int i; - - for (i = 0; i < NUM_BUCKETS; i++) - INIT_LIST_HEAD(buckets + i); -} - -int dm_hash_init(void) -{ - init_buckets(_name_buckets); - init_buckets(_uuid_buckets); - devfs_mk_dir(DM_DIR); - return 0; -} - -void dm_hash_exit(void) -{ - dm_hash_remove_all(); - devfs_remove(DM_DIR); -} - -/*----------------------------------------------------------------- - * Hash function: - * We're not really concerned with the str hash function being - * fast since it's only used by the ioctl interface. - *---------------------------------------------------------------*/ -static unsigned int hash_str(const char *str) -{ - const unsigned int hash_mult = 2654435387U; - unsigned int h = 0; - - while (*str) - h = (h + (unsigned int) *str++) * hash_mult; - - return h & MASK_BUCKETS; -} - -/*----------------------------------------------------------------- - * Code for looking up a device by name - *---------------------------------------------------------------*/ -static struct hash_cell *__get_name_cell(const char *str) -{ - struct list_head *tmp; - struct hash_cell *hc; - unsigned int h = hash_str(str); - - list_for_each (tmp, _name_buckets + h) { - hc = list_entry(tmp, struct hash_cell, name_list); - if (!strcmp(hc->name, str)) - return hc; - } - - return NULL; -} - -static struct hash_cell *__get_uuid_cell(const char *str) -{ - struct list_head *tmp; - struct hash_cell *hc; - unsigned int h = hash_str(str); - - list_for_each (tmp, _uuid_buckets + h) { - hc = list_entry(tmp, struct hash_cell, uuid_list); - if (!strcmp(hc->uuid, str)) - return hc; - } - - return NULL; -} - -/*----------------------------------------------------------------- - * Inserting, removing and renaming a device. - *---------------------------------------------------------------*/ -static inline char *kstrdup(const char *str) -{ - char *r = kmalloc(strlen(str) + 1, GFP_KERNEL); - if (r) - strcpy(r, str); - return r; -} - -static struct hash_cell *alloc_cell(const char *name, const char *uuid, - struct mapped_device *md) -{ - struct hash_cell *hc; - - hc = kmalloc(sizeof(*hc), GFP_KERNEL); - if (!hc) - return NULL; - - hc->name = kstrdup(name); - if (!hc->name) { - kfree(hc); - return NULL; - } - - if (!uuid) - hc->uuid = NULL; - - else { - hc->uuid = kstrdup(uuid); - if (!hc->uuid) { - kfree(hc->name); - kfree(hc); - return NULL; - } - } - - INIT_LIST_HEAD(&hc->name_list); - INIT_LIST_HEAD(&hc->uuid_list); - hc->md = md; - return hc; -} - -static void free_cell(struct hash_cell *hc) -{ - if (hc) { - kfree(hc->name); - kfree(hc->uuid); - kfree(hc); - } -} - -/* - * devfs stuff. - */ -static int register_with_devfs(struct hash_cell *hc) -{ - struct gendisk *disk = dm_disk(hc->md); - - devfs_mk_bdev(MKDEV(disk->major, disk->first_minor), - S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, - DM_DIR "/%s", hc->name); - return 0; -} - -static int unregister_with_devfs(struct hash_cell *hc) -{ - devfs_remove(DM_DIR"/%s", hc->name); - return 0; -} - -/* - * The kdev_t and uuid of a device can never change once it is - * initially inserted. - */ -int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) -{ - struct hash_cell *cell; - - /* - * Allocate the new cells. - */ - cell = alloc_cell(name, uuid, md); - if (!cell) - return -ENOMEM; - - /* - * Insert the cell into all three hash tables. - */ - down_write(&_hash_lock); - if (__get_name_cell(name)) - goto bad; - - list_add(&cell->name_list, _name_buckets + hash_str(name)); - - if (uuid) { - if (__get_uuid_cell(uuid)) { - list_del(&cell->name_list); - goto bad; - } - list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); - } - register_with_devfs(cell); - dm_get(md); - up_write(&_hash_lock); - - return 0; - - bad: - up_write(&_hash_lock); - free_cell(cell); - return -EBUSY; -} - -void __hash_remove(struct hash_cell *hc) -{ - /* remove from the dev hash */ - list_del(&hc->uuid_list); - list_del(&hc->name_list); - unregister_with_devfs(hc); - dm_put(hc->md); - free_cell(hc); -} - -void dm_hash_remove_all(void) -{ - int i; - struct hash_cell *hc; - struct list_head *tmp, *n; - - down_write(&_hash_lock); - for (i = 0; i < NUM_BUCKETS; i++) { - list_for_each_safe (tmp, n, _name_buckets + i) { - hc = list_entry(tmp, struct hash_cell, name_list); - __hash_remove(hc); - } - } - up_write(&_hash_lock); -} - -int dm_hash_rename(const char *old, const char *new) -{ - char *new_name, *old_name; - struct hash_cell *hc; - - /* - * duplicate new. - */ - new_name = kstrdup(new); - if (!new_name) - return -ENOMEM; - - down_write(&_hash_lock); - - /* - * Is new free ? - */ - hc = __get_name_cell(new); - if (hc) { - DMWARN("asked to rename to an already existing name %s -> %s", - old, new); - up_write(&_hash_lock); - kfree(new_name); - return -EBUSY; - } - - /* - * Is there such a device as 'old' ? - */ - hc = __get_name_cell(old); - if (!hc) { - DMWARN("asked to rename a non existent device %s -> %s", - old, new); - up_write(&_hash_lock); - kfree(new_name); - return -ENXIO; - } - - /* - * rename and move the name cell. - */ - unregister_with_devfs(hc); - - list_del(&hc->name_list); - old_name = hc->name; - hc->name = new_name; - list_add(&hc->name_list, _name_buckets + hash_str(new_name)); - - /* rename the device node in devfs */ - register_with_devfs(hc); - - up_write(&_hash_lock); - kfree(old_name); - return 0; -} - - -/*----------------------------------------------------------------- - * Implementation of the ioctl commands - *---------------------------------------------------------------*/ - -/* - * All the ioctl commands get dispatched to functions with this - * prototype. - */ -typedef int (*ioctl_fn)(struct dm_ioctl *param, struct dm_ioctl *user); - -/* - * Check a string doesn't overrun the chunk of - * memory we copied from userland. - */ -static int valid_str(char *str, void *begin, void *end) -{ - while (((void *) str >= begin) && ((void *) str < end)) - if (!*str++) - return 0; - - return -EINVAL; -} - -static int next_target(struct dm_target_spec *last, uint32_t next, - void *begin, void *end, - struct dm_target_spec **spec, char **params) -{ - *spec = (struct dm_target_spec *) - ((unsigned char *) last + next); - *params = (char *) (*spec + 1); - - if (*spec < (last + 1) || ((void *) *spec > end)) - return -EINVAL; - - return valid_str(*params, begin, end); -} - -static int populate_table(struct dm_table *table, struct dm_ioctl *args) -{ - int r, first = 1; - unsigned int i = 0; - struct dm_target_spec *spec; - char *params; - void *begin, *end; - - if (!args->target_count) { - DMWARN("populate_table: no targets specified"); - return -EINVAL; - } - - begin = (void *) args; - end = begin + args->data_size; - - for (i = 0; i < args->target_count; i++) { - - if (first) - r = next_target((struct dm_target_spec *) args, - args->data_start, - begin, end, &spec, ¶ms); - else - r = next_target(spec, spec->next, begin, end, - &spec, ¶ms); - - if (r) { - DMWARN("unable to find target"); - return -EINVAL; - } - - r = dm_table_add_target(table, spec->target_type, - (sector_t) spec->sector_start, - (sector_t) spec->length, - params); - if (r) { - DMWARN("internal error adding target to table"); - return -EINVAL; - } - - first = 0; - } - - return dm_table_complete(table); -} - -/* - * Round up the ptr to the next 'align' boundary. Obviously - * 'align' must be a power of 2. - */ -static inline void *align_ptr(void *ptr, unsigned int align) -{ - align--; - return (void *) (((unsigned long) (ptr + align)) & ~align); -} - -/* - * Copies a dm_ioctl and an optional additional payload to - * userland. - */ -static int results_to_user(struct dm_ioctl *user, struct dm_ioctl *param, - void *data, uint32_t len) -{ - int r; - void *ptr = NULL; - - if (data) { - ptr = align_ptr(user + 1, sizeof(unsigned long)); - param->data_start = ptr - (void *) user; - } - - /* - * The version number has already been filled in, so we - * just copy later fields. - */ - r = copy_to_user(&user->data_size, ¶m->data_size, - sizeof(*param) - sizeof(param->version)); - if (r) - return -EFAULT; - - if (data) { - if (param->data_start + len > param->data_size) - return -ENOSPC; - - if (copy_to_user(ptr, data, len)) - r = -EFAULT; - } - - return r; -} - -/* - * Fills in a dm_ioctl structure, ready for sending back to - * userland. - */ -static int __info(struct mapped_device *md, struct dm_ioctl *param) -{ - struct dm_table *table; - struct block_device *bdev; - struct gendisk *disk = dm_disk(md); - - param->flags = DM_EXISTS_FLAG; - if (dm_suspended(md)) - param->flags |= DM_SUSPEND_FLAG; - - bdev = bdget_disk(disk, 0); - if (!bdev) - return -ENXIO; - - param->dev = old_encode_dev(bdev->bd_dev); - param->open_count = bdev->bd_openers; - bdput(bdev); - - if (disk->policy) - param->flags |= DM_READONLY_FLAG; - - table = dm_get_table(md); - param->target_count = dm_table_get_num_targets(table); - dm_table_put(table); - - return 0; -} - -/* - * Always use UUID for lookups if it's present, otherwise use name. - */ -static inline struct mapped_device *find_device(struct dm_ioctl *param) -{ - struct hash_cell *hc; - struct mapped_device *md = NULL; - - down_read(&_hash_lock); - hc = *param->uuid ? __get_uuid_cell(param->uuid) : - __get_name_cell(param->name); - if (hc) { - md = hc->md; - - /* - * Sneakily write in both the name and the uuid - * while we have the cell. - */ - strlcpy(param->name, hc->name, sizeof(param->name)); - if (hc->uuid) - strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); - else - param->uuid[0] = '\0'; - - dm_get(md); - } - up_read(&_hash_lock); - - return md; -} - -#define ALIGNMENT sizeof(int) -static void *_align(void *ptr, unsigned int a) -{ - register unsigned long align = --a; - - return (void *) (((unsigned long) ptr + align) & ~align); -} - -/* - * Copies device info back to user space, used by - * the create and info ioctls. - */ -static int info(struct dm_ioctl *param, struct dm_ioctl *user) -{ - struct mapped_device *md; - - param->flags = 0; - - md = find_device(param); - if (!md) - /* - * Device not found - returns cleared exists flag. - */ - goto out; - - __info(md, param); - dm_put(md); - - out: - return results_to_user(user, param, NULL, 0); -} - -static inline int get_mode(struct dm_ioctl *param) -{ - int mode = FMODE_READ | FMODE_WRITE; - - if (param->flags & DM_READONLY_FLAG) - mode = FMODE_READ; - - return mode; -} - -static int check_name(const char *name) -{ - if (name[0] == '/') { - DMWARN("invalid device name"); - return -EINVAL; - } - - return 0; -} - -static int create(struct dm_ioctl *param, struct dm_ioctl *user) -{ - int r; - struct dm_table *t; - struct mapped_device *md; - - r = check_name(param->name); - if (r) - return r; - - r = dm_table_create(&t, get_mode(param), param->target_count); - if (r) - return r; - - r = populate_table(t, param); - if (r) { - dm_table_put(t); - return r; - } - - if (param->flags & DM_PERSISTENT_DEV_FLAG) - r = dm_create_with_minor(MINOR(old_decode_dev(param->dev)), &md); - else - r = dm_create(&md); - - if (r) { - dm_table_put(t); - return r; - } - - /* suspend the device */ - r = dm_suspend(md); - if (r) { - DMWARN("suspend failed"); - dm_table_put(t); - dm_put(md); - return r; - } - /* swap in the table */ - r = dm_swap_table(md, t); - if (r) { - DMWARN("table swap failed"); - dm_table_put(t); - dm_put(md); - return r; - } - - /* resume the device */ - r = dm_resume(md); - if (r) { - DMWARN("resume failed"); - dm_table_put(t); - dm_put(md); - return r; - } - - dm_table_put(t); /* md will have grabbed its own reference */ - - set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0); - r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); - dm_put(md); - - return r ? r : info(param, user); -} - -/* - * Build up the status struct for each target - */ -static int __status(struct mapped_device *md, struct dm_ioctl *param, - char *outbuf, size_t *len) -{ - unsigned int i, num_targets; - struct dm_target_spec *spec; - char *outptr; - status_type_t type; - struct dm_table *table = dm_get_table(md); - - if (param->flags & DM_STATUS_TABLE_FLAG) - type = STATUSTYPE_TABLE; - else - type = STATUSTYPE_INFO; - - outptr = outbuf; - - /* Get all the target info */ - num_targets = dm_table_get_num_targets(table); - for (i = 0; i < num_targets; i++) { - struct dm_target *ti = dm_table_get_target(table, i); - - if (outptr - outbuf + - sizeof(struct dm_target_spec) > param->data_size) { - dm_table_put(table); - return -ENOMEM; - } - - spec = (struct dm_target_spec *) outptr; - - spec->status = 0; - spec->sector_start = ti->begin; - spec->length = ti->len; - strlcpy(spec->target_type, ti->type->name, - sizeof(spec->target_type)); - - outptr += sizeof(struct dm_target_spec); - - /* Get the status/table string from the target driver */ - if (ti->type->status) - ti->type->status(ti, type, outptr, - outbuf + param->data_size - outptr); - else - outptr[0] = '\0'; - - outptr += strlen(outptr) + 1; - _align(outptr, ALIGNMENT); - spec->next = outptr - outbuf; - } - - param->target_count = num_targets; - *len = outptr - outbuf; - dm_table_put(table); - - return 0; -} - -/* - * Return the status of a device as a text string for each - * target. - */ -static int get_status(struct dm_ioctl *param, struct dm_ioctl *user) -{ - struct mapped_device *md; - size_t len = 0; - int ret; - char *outbuf = NULL; - - md = find_device(param); - if (!md) - /* - * Device not found - returns cleared exists flag. - */ - goto out; - - /* We haven't a clue how long the resultant data will be so - just allocate as much as userland has allowed us and make sure - we don't overun it */ - outbuf = kmalloc(param->data_size, GFP_KERNEL); - if (!outbuf) - goto out; - /* - * Get the status of all targets - */ - __status(md, param, outbuf, &len); - - /* - * Setup the basic dm_ioctl structure. - */ - __info(md, param); - - out: - if (md) - dm_put(md); - - ret = results_to_user(user, param, outbuf, len); - - if (outbuf) - kfree(outbuf); - - return ret; -} - -/* - * Wait for a device to report an event - */ -static int wait_device_event(struct dm_ioctl *param, struct dm_ioctl *user) -{ - struct mapped_device *md; - DECLARE_WAITQUEUE(wq, current); - - md = find_device(param); - if (!md) - /* - * Device not found - returns cleared exists flag. - */ - goto out; - - /* - * Setup the basic dm_ioctl structure. - */ - __info(md, param); - - /* - * Wait for a notification event - */ - set_current_state(TASK_INTERRUPTIBLE); - if (!dm_add_wait_queue(md, &wq, dm_get_event_nr(md))) { - schedule(); - dm_remove_wait_queue(md, &wq); - } - set_current_state(TASK_RUNNING); - dm_put(md); - - out: - return results_to_user(user, param, NULL, 0); -} - -/* - * Retrieves a list of devices used by a particular dm device. - */ -static int dep(struct dm_ioctl *param, struct dm_ioctl *user) -{ - int r; - unsigned int count; - struct mapped_device *md; - struct list_head *tmp; - size_t len = 0; - struct dm_target_deps *deps = NULL; - struct dm_table *table; - - md = find_device(param); - if (!md) - goto out; - table = dm_get_table(md); - - /* - * Setup the basic dm_ioctl structure. - */ - __info(md, param); - - /* - * Count the devices. - */ - count = 0; - list_for_each(tmp, dm_table_get_devices(table)) - count++; - - /* - * Allocate a kernel space version of the dm_target_status - * struct. - */ - if (array_too_big(sizeof(*deps), sizeof(*deps->dev), count)) { - dm_table_put(table); - dm_put(md); - return -ENOMEM; - } - - len = sizeof(*deps) + (sizeof(*deps->dev) * count); - deps = kmalloc(len, GFP_KERNEL); - if (!deps) { - dm_table_put(table); - dm_put(md); - return -ENOMEM; - } - - /* - * Fill in the devices. - */ - deps->count = count; - count = 0; - list_for_each(tmp, dm_table_get_devices(table)) { - struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); - deps->dev[count++] = old_encode_dev(dd->bdev->bd_dev); - } - dm_table_put(table); - dm_put(md); - - out: - r = results_to_user(user, param, deps, len); - - kfree(deps); - return r; -} - -static int remove(struct dm_ioctl *param, struct dm_ioctl *user) -{ - struct hash_cell *hc; - - down_write(&_hash_lock); - hc = *param->uuid ? __get_uuid_cell(param->uuid) : - __get_name_cell(param->name); - if (!hc) { - DMWARN("device doesn't appear to be in the dev hash table."); - up_write(&_hash_lock); - return -EINVAL; - } - - /* - * You may ask the interface to drop its reference to an - * in use device. This is no different to unlinking a - * file that someone still has open. The device will not - * actually be destroyed until the last opener closes it. - * The name and uuid of the device (both are interface - * properties) will be available for reuse immediately. - * - * You don't want to drop a _suspended_ device from the - * interface, since that will leave you with no way of - * resuming it. - */ - if (dm_suspended(hc->md)) { - DMWARN("refusing to remove a suspended device."); - up_write(&_hash_lock); - return -EPERM; - } - - __hash_remove(hc); - up_write(&_hash_lock); - return 0; -} - -static int remove_all(struct dm_ioctl *param, struct dm_ioctl *user) -{ - dm_hash_remove_all(); - return 0; -} - -static int suspend(struct dm_ioctl *param, struct dm_ioctl *user) -{ - int r; - struct mapped_device *md; - - md = find_device(param); - if (!md) - return -ENXIO; - - if (param->flags & DM_SUSPEND_FLAG) - r = dm_suspend(md); - else - r = dm_resume(md); - - dm_put(md); - return r; -} - -static int reload(struct dm_ioctl *param, struct dm_ioctl *user) -{ - int r; - struct mapped_device *md; - struct dm_table *t; - - r = dm_table_create(&t, get_mode(param), param->target_count); - if (r) - return r; - - r = populate_table(t, param); - if (r) { - dm_table_put(t); - return r; - } - - md = find_device(param); - if (!md) { - dm_table_put(t); - return -ENXIO; - } - - r = dm_swap_table(md, t); - if (r) { - dm_put(md); - dm_table_put(t); - return r; - } - dm_table_put(t); /* md will have taken its own reference */ - - set_disk_ro(dm_disk(md), (param->flags & DM_READONLY_FLAG) ? 1 : 0); - dm_put(md); - - r = info(param, user); - return r; -} - -static int rename(struct dm_ioctl *param, struct dm_ioctl *user) -{ - int r; - char *new_name = (char *) param + param->data_start; - - if (valid_str(new_name, (void *) param, - (void *) param + param->data_size)) { - DMWARN("Invalid new logical volume name supplied."); - return -EINVAL; - } - - r = check_name(new_name); - if (r) - return r; - - return dm_hash_rename(param->name, new_name); -} - - -/*----------------------------------------------------------------- - * Implementation of open/close/ioctl on the special char - * device. - *---------------------------------------------------------------*/ -static ioctl_fn lookup_ioctl(unsigned int cmd) -{ - static struct { - int cmd; - ioctl_fn fn; - } _ioctls[] = { - {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ - {DM_REMOVE_ALL_CMD, remove_all}, - {DM_DEV_CREATE_CMD, create}, - {DM_DEV_REMOVE_CMD, remove}, - {DM_DEV_RELOAD_CMD, reload}, - {DM_DEV_RENAME_CMD, rename}, - {DM_DEV_SUSPEND_CMD, suspend}, - {DM_DEV_DEPS_CMD, dep}, - {DM_DEV_STATUS_CMD, info}, - {DM_TARGET_STATUS_CMD, get_status}, - {DM_TARGET_WAIT_CMD, wait_device_event}, - }; - - return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; -} - -/* - * As well as checking the version compatibility this always - * copies the kernel interface version out. - */ -static int check_version(unsigned int cmd, struct dm_ioctl *user) -{ - uint32_t version[3]; - int r = 0; - - if (copy_from_user(version, user->version, sizeof(version))) - return -EFAULT; - - if ((DM_VERSION_MAJOR != version[0]) || - (DM_VERSION_MINOR < version[1])) { - DMWARN("ioctl interface mismatch: " - "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", - DM_VERSION_MAJOR, DM_VERSION_MINOR, - DM_VERSION_PATCHLEVEL, - version[0], version[1], version[2], cmd); - r = -EINVAL; - } - - /* - * Fill in the kernel version. - */ - version[0] = DM_VERSION_MAJOR; - version[1] = DM_VERSION_MINOR; - version[2] = DM_VERSION_PATCHLEVEL; - if (copy_to_user(user->version, version, sizeof(version))) - return -EFAULT; - - return r; -} - -static void free_params(struct dm_ioctl *param) -{ - vfree(param); -} - -static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param) -{ - struct dm_ioctl tmp, *dmi; - - if (copy_from_user(&tmp, user, sizeof(tmp))) - return -EFAULT; - - if (tmp.data_size < sizeof(tmp)) - return -EINVAL; - - dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); - if (!dmi) - return -ENOMEM; - - if (copy_from_user(dmi, user, tmp.data_size)) { - vfree(dmi); - return -EFAULT; - } - - *param = dmi; - return 0; -} - -static int validate_params(uint cmd, struct dm_ioctl *param) -{ - /* Ignores parameters */ - if (cmd == DM_REMOVE_ALL_CMD) - return 0; - - /* Unless creating, either name of uuid but not both */ - if (cmd != DM_DEV_CREATE_CMD) { - if ((!*param->uuid && !*param->name) || - (*param->uuid && *param->name)) { - DMWARN("one of name or uuid must be supplied"); - return -EINVAL; - } - } - - /* Ensure strings are terminated */ - param->name[DM_NAME_LEN - 1] = '\0'; - param->uuid[DM_UUID_LEN - 1] = '\0'; - - return 0; -} - -static int ctl_ioctl(struct inode *inode, struct file *file, - uint command, ulong u) -{ - int r = 0; - unsigned int cmd; - struct dm_ioctl *param; - struct dm_ioctl *user = (struct dm_ioctl *) u; - ioctl_fn fn = NULL; - - /* only root can play with this */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (_IOC_TYPE(command) != DM_IOCTL) - return -ENOTTY; - - cmd = _IOC_NR(command); - - /* - * Check the interface version passed in. This also - * writes out the kernels interface version. - */ - r = check_version(cmd, user); - if (r) - return r; - - /* - * Nothing more to do for the version command. - */ - if (cmd == DM_VERSION_CMD) - return 0; - - fn = lookup_ioctl(cmd); - if (!fn) { - DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); - return -ENOTTY; - } - - /* - * Copy the parameters into kernel space. - */ - r = copy_params(user, ¶m); - if (r) - return r; - - r = validate_params(cmd, param); - if (r) { - free_params(param); - return r; - } - - r = fn(param, user); - free_params(param); - return r; -} - -static struct file_operations _ctl_fops = { - .ioctl = ctl_ioctl, - .owner = THIS_MODULE, -}; - -static struct miscdevice _dm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = DM_NAME, - .devfs_name = "mapper/control", - .fops = &_ctl_fops -}; - -/* - * Create misc character device and link to DM_DIR/control. - */ -int __init dm_interface_init(void) -{ - int r; - - r = dm_hash_init(); - if (r) - return r; - - r = misc_register(&_dm_misc); - if (r) { - DMERR("misc_register failed for control device"); - dm_hash_exit(); - return r; - } - - DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, - DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, - DM_DRIVER_EMAIL); - return 0; - - if (misc_deregister(&_dm_misc) < 0) - DMERR("misc_deregister failed for control device"); - dm_hash_exit(); - return r; -} - -void dm_interface_exit(void) -{ - if (misc_deregister(&_dm_misc) < 0) - DMERR("misc_deregister failed for control device"); - dm_hash_exit(); -} diff -Nru a/drivers/md/dm-ioctl-v4.c b/drivers/md/dm-ioctl-v4.c --- a/drivers/md/dm-ioctl-v4.c Sun Mar 7 18:39:36 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1264 +0,0 @@ -/* - * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. - * - * This file is released under the GPL. - */ - -#include "dm.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define DM_DRIVER_EMAIL "dm@uk.sistina.com" - -/*----------------------------------------------------------------- - * The ioctl interface needs to be able to look up devices by - * name or uuid. - *---------------------------------------------------------------*/ -struct hash_cell { - struct list_head name_list; - struct list_head uuid_list; - - char *name; - char *uuid; - struct mapped_device *md; - struct dm_table *new_map; -}; - -#define NUM_BUCKETS 64 -#define MASK_BUCKETS (NUM_BUCKETS - 1) -static struct list_head _name_buckets[NUM_BUCKETS]; -static struct list_head _uuid_buckets[NUM_BUCKETS]; - -void dm_hash_remove_all(void); - -/* - * Guards access to both hash tables. - */ -static DECLARE_RWSEM(_hash_lock); - -static void init_buckets(struct list_head *buckets) -{ - unsigned int i; - - for (i = 0; i < NUM_BUCKETS; i++) - INIT_LIST_HEAD(buckets + i); -} - -int dm_hash_init(void) -{ - init_buckets(_name_buckets); - init_buckets(_uuid_buckets); - devfs_mk_dir(DM_DIR); - return 0; -} - -void dm_hash_exit(void) -{ - dm_hash_remove_all(); - devfs_remove(DM_DIR); -} - -/*----------------------------------------------------------------- - * Hash function: - * We're not really concerned with the str hash function being - * fast since it's only used by the ioctl interface. - *---------------------------------------------------------------*/ -static unsigned int hash_str(const char *str) -{ - const unsigned int hash_mult = 2654435387U; - unsigned int h = 0; - - while (*str) - h = (h + (unsigned int) *str++) * hash_mult; - - return h & MASK_BUCKETS; -} - -/*----------------------------------------------------------------- - * Code for looking up a device by name - *---------------------------------------------------------------*/ -static struct hash_cell *__get_name_cell(const char *str) -{ - struct list_head *tmp; - struct hash_cell *hc; - unsigned int h = hash_str(str); - - list_for_each (tmp, _name_buckets + h) { - hc = list_entry(tmp, struct hash_cell, name_list); - if (!strcmp(hc->name, str)) - return hc; - } - - return NULL; -} - -static struct hash_cell *__get_uuid_cell(const char *str) -{ - struct list_head *tmp; - struct hash_cell *hc; - unsigned int h = hash_str(str); - - list_for_each (tmp, _uuid_buckets + h) { - hc = list_entry(tmp, struct hash_cell, uuid_list); - if (!strcmp(hc->uuid, str)) - return hc; - } - - return NULL; -} - -/*----------------------------------------------------------------- - * Inserting, removing and renaming a device. - *---------------------------------------------------------------*/ -static inline char *kstrdup(const char *str) -{ - char *r = kmalloc(strlen(str) + 1, GFP_KERNEL); - if (r) - strcpy(r, str); - return r; -} - -static struct hash_cell *alloc_cell(const char *name, const char *uuid, - struct mapped_device *md) -{ - struct hash_cell *hc; - - hc = kmalloc(sizeof(*hc), GFP_KERNEL); - if (!hc) - return NULL; - - hc->name = kstrdup(name); - if (!hc->name) { - kfree(hc); - return NULL; - } - - if (!uuid) - hc->uuid = NULL; - - else { - hc->uuid = kstrdup(uuid); - if (!hc->uuid) { - kfree(hc->name); - kfree(hc); - return NULL; - } - } - - INIT_LIST_HEAD(&hc->name_list); - INIT_LIST_HEAD(&hc->uuid_list); - hc->md = md; - hc->new_map = NULL; - return hc; -} - -static void free_cell(struct hash_cell *hc) -{ - if (hc) { - kfree(hc->name); - kfree(hc->uuid); - kfree(hc); - } -} - -/* - * devfs stuff. - */ -static int register_with_devfs(struct hash_cell *hc) -{ - struct gendisk *disk = dm_disk(hc->md); - - devfs_mk_bdev(MKDEV(disk->major, disk->first_minor), - S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, - DM_DIR "/%s", hc->name); - return 0; -} - -static int unregister_with_devfs(struct hash_cell *hc) -{ - devfs_remove(DM_DIR"/%s", hc->name); - return 0; -} - -/* - * The kdev_t and uuid of a device can never change once it is - * initially inserted. - */ -int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) -{ - struct hash_cell *cell; - - /* - * Allocate the new cells. - */ - cell = alloc_cell(name, uuid, md); - if (!cell) - return -ENOMEM; - - /* - * Insert the cell into both hash tables. - */ - down_write(&_hash_lock); - if (__get_name_cell(name)) - goto bad; - - list_add(&cell->name_list, _name_buckets + hash_str(name)); - - if (uuid) { - if (__get_uuid_cell(uuid)) { - list_del(&cell->name_list); - goto bad; - } - list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); - } - register_with_devfs(cell); - dm_get(md); - up_write(&_hash_lock); - - return 0; - - bad: - up_write(&_hash_lock); - free_cell(cell); - return -EBUSY; -} - -void __hash_remove(struct hash_cell *hc) -{ - /* remove from the dev hash */ - list_del(&hc->uuid_list); - list_del(&hc->name_list); - unregister_with_devfs(hc); - dm_put(hc->md); - if (hc->new_map) - dm_table_put(hc->new_map); - free_cell(hc); -} - -void dm_hash_remove_all(void) -{ - int i; - struct hash_cell *hc; - struct list_head *tmp, *n; - - down_write(&_hash_lock); - for (i = 0; i < NUM_BUCKETS; i++) { - list_for_each_safe (tmp, n, _name_buckets + i) { - hc = list_entry(tmp, struct hash_cell, name_list); - __hash_remove(hc); - } - } - up_write(&_hash_lock); -} - -int dm_hash_rename(const char *old, const char *new) -{ - char *new_name, *old_name; - struct hash_cell *hc; - - /* - * duplicate new. - */ - new_name = kstrdup(new); - if (!new_name) - return -ENOMEM; - - down_write(&_hash_lock); - - /* - * Is new free ? - */ - hc = __get_name_cell(new); - if (hc) { - DMWARN("asked to rename to an already existing name %s -> %s", - old, new); - up_write(&_hash_lock); - kfree(new_name); - return -EBUSY; - } - - /* - * Is there such a device as 'old' ? - */ - hc = __get_name_cell(old); - if (!hc) { - DMWARN("asked to rename a non existent device %s -> %s", - old, new); - up_write(&_hash_lock); - kfree(new_name); - return -ENXIO; - } - - /* - * rename and move the name cell. - */ - unregister_with_devfs(hc); - - list_del(&hc->name_list); - old_name = hc->name; - hc->name = new_name; - list_add(&hc->name_list, _name_buckets + hash_str(new_name)); - - /* rename the device node in devfs */ - register_with_devfs(hc); - - up_write(&_hash_lock); - kfree(old_name); - return 0; -} - -/*----------------------------------------------------------------- - * Implementation of the ioctl commands - *---------------------------------------------------------------*/ -/* - * All the ioctl commands get dispatched to functions with this - * prototype. - */ -typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size); - -static int remove_all(struct dm_ioctl *param, size_t param_size) -{ - dm_hash_remove_all(); - param->data_size = 0; - return 0; -} - -/* - * Round up the ptr to an 8-byte boundary. - */ -#define ALIGN_MASK 7 -static inline void *align_ptr(void *ptr) -{ - return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK); -} - -/* - * Retrieves the data payload buffer from an already allocated - * struct dm_ioctl. - */ -static void *get_result_buffer(struct dm_ioctl *param, size_t param_size, - size_t *len) -{ - param->data_start = align_ptr(param + 1) - (void *) param; - - if (param->data_start < param_size) - *len = param_size - param->data_start; - else - *len = 0; - - return ((void *) param) + param->data_start; -} - -static int list_devices(struct dm_ioctl *param, size_t param_size) -{ - unsigned int i; - struct hash_cell *hc; - size_t len, needed = 0; - struct gendisk *disk; - struct dm_name_list *nl, *old_nl = NULL; - - down_write(&_hash_lock); - - /* - * Loop through all the devices working out how much - * space we need. - */ - for (i = 0; i < NUM_BUCKETS; i++) { - list_for_each_entry (hc, _name_buckets + i, name_list) { - needed += sizeof(struct dm_name_list); - needed += strlen(hc->name); - needed += ALIGN_MASK; - } - } - - /* - * Grab our output buffer. - */ - nl = get_result_buffer(param, param_size, &len); - if (len < needed) { - param->flags |= DM_BUFFER_FULL_FLAG; - goto out; - } - param->data_size = param->data_start + needed; - - nl->dev = 0; /* Flags no data */ - - /* - * Now loop through filling out the names. - */ - for (i = 0; i < NUM_BUCKETS; i++) { - list_for_each_entry (hc, _name_buckets + i, name_list) { - if (old_nl) - old_nl->next = (uint32_t) ((void *) nl - - (void *) old_nl); - disk = dm_disk(hc->md); - nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); - nl->next = 0; - strcpy(nl->name, hc->name); - - old_nl = nl; - nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1); - } - } - - out: - up_write(&_hash_lock); - return 0; -} - -static int check_name(const char *name) -{ - if (strchr(name, '/')) { - DMWARN("invalid device name"); - return -EINVAL; - } - - return 0; -} - -/* - * Fills in a dm_ioctl structure, ready for sending back to - * userland. - */ -static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) -{ - struct gendisk *disk = dm_disk(md); - struct dm_table *table; - struct block_device *bdev; - - param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | - DM_ACTIVE_PRESENT_FLAG); - - if (dm_suspended(md)) - param->flags |= DM_SUSPEND_FLAG; - - bdev = bdget_disk(disk, 0); - if (!bdev) - return -ENXIO; - - param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); - - /* - * Yes, this will be out of date by the time it gets back - * to userland, but it is still very useful ofr - * debugging. - */ - param->open_count = bdev->bd_openers; - bdput(bdev); - - if (disk->policy) - param->flags |= DM_READONLY_FLAG; - - param->event_nr = dm_get_event_nr(md); - - table = dm_get_table(md); - if (table) { - param->flags |= DM_ACTIVE_PRESENT_FLAG; - param->target_count = dm_table_get_num_targets(table); - dm_table_put(table); - } else - param->target_count = 0; - - return 0; -} - -static int dev_create(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct mapped_device *md; - - r = check_name(param->name); - if (r) - return r; - - if (param->flags & DM_PERSISTENT_DEV_FLAG) - r = dm_create_with_minor(MINOR(huge_decode_dev(param->dev)), &md); - else - r = dm_create(&md); - - if (r) - return r; - - r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); - if (r) { - dm_put(md); - return r; - } - - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - r = __dev_status(md, param); - dm_put(md); - - return r; -} - -/* - * Always use UUID for lookups if it's present, otherwise use name. - */ -static inline struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) -{ - return *param->uuid ? - __get_uuid_cell(param->uuid) : __get_name_cell(param->name); -} - -static inline struct mapped_device *find_device(struct dm_ioctl *param) -{ - struct hash_cell *hc; - struct mapped_device *md = NULL; - - down_read(&_hash_lock); - hc = __find_device_hash_cell(param); - if (hc) { - md = hc->md; - - /* - * Sneakily write in both the name and the uuid - * while we have the cell. - */ - strncpy(param->name, hc->name, sizeof(param->name)); - if (hc->uuid) - strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1); - else - param->uuid[0] = '\0'; - - if (hc->new_map) - param->flags |= DM_INACTIVE_PRESENT_FLAG; - else - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - dm_get(md); - } - up_read(&_hash_lock); - - return md; -} - -static int dev_remove(struct dm_ioctl *param, size_t param_size) -{ - struct hash_cell *hc; - - down_write(&_hash_lock); - hc = __find_device_hash_cell(param); - - if (!hc) { - DMWARN("device doesn't appear to be in the dev hash table."); - up_write(&_hash_lock); - return -ENXIO; - } - - __hash_remove(hc); - up_write(&_hash_lock); - param->data_size = 0; - return 0; -} - -/* - * Check a string doesn't overrun the chunk of - * memory we copied from userland. - */ -static int invalid_str(char *str, void *end) -{ - while ((void *) str < end) - if (!*str++) - return 0; - - return -EINVAL; -} - -static int dev_rename(struct dm_ioctl *param, size_t param_size) -{ - int r; - char *new_name = (char *) param + param->data_start; - - if (new_name < (char *) (param + 1) || - invalid_str(new_name, (void *) param + param_size)) { - DMWARN("Invalid new logical volume name supplied."); - return -EINVAL; - } - - r = check_name(new_name); - if (r) - return r; - - param->data_size = 0; - return dm_hash_rename(param->name, new_name); -} - -static int do_suspend(struct dm_ioctl *param) -{ - int r = 0; - struct mapped_device *md; - - md = find_device(param); - if (!md) - return -ENXIO; - - if (!dm_suspended(md)) - r = dm_suspend(md); - - if (!r) - r = __dev_status(md, param); - - dm_put(md); - return r; -} - -static int do_resume(struct dm_ioctl *param) -{ - int r = 0; - struct hash_cell *hc; - struct mapped_device *md; - struct dm_table *new_map; - - down_write(&_hash_lock); - - hc = __find_device_hash_cell(param); - if (!hc) { - DMWARN("device doesn't appear to be in the dev hash table."); - up_write(&_hash_lock); - return -ENXIO; - } - - md = hc->md; - dm_get(md); - - new_map = hc->new_map; - hc->new_map = NULL; - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - up_write(&_hash_lock); - - /* Do we need to load a new map ? */ - if (new_map) { - /* Suspend if it isn't already suspended */ - if (!dm_suspended(md)) - dm_suspend(md); - - r = dm_swap_table(md, new_map); - if (r) { - dm_put(md); - dm_table_put(new_map); - return r; - } - - if (dm_table_get_mode(new_map) & FMODE_WRITE) - set_disk_ro(dm_disk(md), 0); - else - set_disk_ro(dm_disk(md), 1); - - dm_table_put(new_map); - } - - if (dm_suspended(md)) - r = dm_resume(md); - - if (!r) - r = __dev_status(md, param); - - dm_put(md); - return r; -} - -/* - * Set or unset the suspension state of a device. - * If the device already is in the requested state we just return its status. - */ -static int dev_suspend(struct dm_ioctl *param, size_t param_size) -{ - if (param->flags & DM_SUSPEND_FLAG) - return do_suspend(param); - - return do_resume(param); -} - -/* - * Copies device info back to user space, used by - * the create and info ioctls. - */ -static int dev_status(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct mapped_device *md; - - md = find_device(param); - if (!md) - return -ENXIO; - - r = __dev_status(md, param); - dm_put(md); - return r; -} - -/* - * Build up the status struct for each target - */ -static void retrieve_status(struct dm_table *table, - struct dm_ioctl *param, size_t param_size) -{ - unsigned int i, num_targets; - struct dm_target_spec *spec; - char *outbuf, *outptr; - status_type_t type; - size_t remaining, len, used = 0; - - outptr = outbuf = get_result_buffer(param, param_size, &len); - - if (param->flags & DM_STATUS_TABLE_FLAG) - type = STATUSTYPE_TABLE; - else - type = STATUSTYPE_INFO; - - /* Get all the target info */ - num_targets = dm_table_get_num_targets(table); - for (i = 0; i < num_targets; i++) { - struct dm_target *ti = dm_table_get_target(table, i); - - remaining = len - (outptr - outbuf); - if (remaining < sizeof(struct dm_target_spec)) { - param->flags |= DM_BUFFER_FULL_FLAG; - break; - } - - spec = (struct dm_target_spec *) outptr; - - spec->status = 0; - spec->sector_start = ti->begin; - spec->length = ti->len; - strncpy(spec->target_type, ti->type->name, - sizeof(spec->target_type)); - - outptr += sizeof(struct dm_target_spec); - remaining = len - (outptr - outbuf); - - /* Get the status/table string from the target driver */ - if (ti->type->status) { - if (ti->type->status(ti, type, outptr, remaining)) { - param->flags |= DM_BUFFER_FULL_FLAG; - break; - } - } else - outptr[0] = '\0'; - - outptr += strlen(outptr) + 1; - used = param->data_start + (outptr - outbuf); - - align_ptr(outptr); - spec->next = outptr - outbuf; - } - - if (used) - param->data_size = used; - - param->target_count = num_targets; -} - -/* - * Wait for a device to report an event - */ -static int dev_wait(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct mapped_device *md; - struct dm_table *table; - DECLARE_WAITQUEUE(wq, current); - - md = find_device(param); - if (!md) - return -ENXIO; - - /* - * Wait for a notification event - */ - set_current_state(TASK_INTERRUPTIBLE); - if (!dm_add_wait_queue(md, &wq, param->event_nr)) { - schedule(); - dm_remove_wait_queue(md, &wq); - } - set_current_state(TASK_RUNNING); - - /* - * The userland program is going to want to know what - * changed to trigger the event, so we may as well tell - * him and save an ioctl. - */ - r = __dev_status(md, param); - if (r) - goto out; - - table = dm_get_table(md); - if (table) { - retrieve_status(table, param, param_size); - dm_table_put(table); - } - - out: - dm_put(md); - return r; -} - -static inline int get_mode(struct dm_ioctl *param) -{ - int mode = FMODE_READ | FMODE_WRITE; - - if (param->flags & DM_READONLY_FLAG) - mode = FMODE_READ; - - return mode; -} - -static int next_target(struct dm_target_spec *last, uint32_t next, void *end, - struct dm_target_spec **spec, char **target_params) -{ - *spec = (struct dm_target_spec *) ((unsigned char *) last + next); - *target_params = (char *) (*spec + 1); - - if (*spec < (last + 1)) - return -EINVAL; - - return invalid_str(*target_params, end); -} - -static int populate_table(struct dm_table *table, - struct dm_ioctl *param, size_t param_size) -{ - int r; - unsigned int i = 0; - struct dm_target_spec *spec = (struct dm_target_spec *) param; - uint32_t next = param->data_start; - void *end = (void *) param + param_size; - char *target_params; - - if (!param->target_count) { - DMWARN("populate_table: no targets specified"); - return -EINVAL; - } - - for (i = 0; i < param->target_count; i++) { - - r = next_target(spec, next, end, &spec, &target_params); - if (r) { - DMWARN("unable to find target"); - return r; - } - - r = dm_table_add_target(table, spec->target_type, - (sector_t) spec->sector_start, - (sector_t) spec->length, - target_params); - if (r) { - DMWARN("error adding target to table"); - return r; - } - - next = spec->next; - } - - return dm_table_complete(table); -} - -static int table_load(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct hash_cell *hc; - struct dm_table *t; - - r = dm_table_create(&t, get_mode(param), param->target_count); - if (r) - return r; - - r = populate_table(t, param, param_size); - if (r) { - dm_table_put(t); - return r; - } - - down_write(&_hash_lock); - hc = __find_device_hash_cell(param); - if (!hc) { - DMWARN("device doesn't appear to be in the dev hash table."); - up_write(&_hash_lock); - return -ENXIO; - } - - if (hc->new_map) - dm_table_put(hc->new_map); - hc->new_map = t; - param->flags |= DM_INACTIVE_PRESENT_FLAG; - - r = __dev_status(hc->md, param); - up_write(&_hash_lock); - return r; -} - -static int table_clear(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct hash_cell *hc; - - down_write(&_hash_lock); - - hc = __find_device_hash_cell(param); - if (!hc) { - DMWARN("device doesn't appear to be in the dev hash table."); - up_write(&_hash_lock); - return -ENXIO; - } - - if (hc->new_map) { - dm_table_put(hc->new_map); - hc->new_map = NULL; - } - - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - r = __dev_status(hc->md, param); - up_write(&_hash_lock); - return r; -} - -/* - * Retrieves a list of devices used by a particular dm device. - */ -static void retrieve_deps(struct dm_table *table, - struct dm_ioctl *param, size_t param_size) -{ - unsigned int count = 0; - struct list_head *tmp; - size_t len, needed; - struct dm_target_deps *deps; - - deps = get_result_buffer(param, param_size, &len); - - /* - * Count the devices. - */ - list_for_each(tmp, dm_table_get_devices(table)) - count++; - - /* - * Check we have enough space. - */ - needed = sizeof(*deps) + (sizeof(*deps->dev) * count); - if (len < needed) { - param->flags |= DM_BUFFER_FULL_FLAG; - return; - } - - /* - * Fill in the devices. - */ - deps->count = count; - count = 0; - list_for_each(tmp, dm_table_get_devices(table)) { - struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); - deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev); - } - - param->data_size = param->data_start + needed; -} - -static int table_deps(struct dm_ioctl *param, size_t param_size) -{ - int r = 0; - struct mapped_device *md; - struct dm_table *table; - - md = find_device(param); - if (!md) - return -ENXIO; - - r = __dev_status(md, param); - if (r) - goto out; - - table = dm_get_table(md); - if (table) { - retrieve_deps(table, param, param_size); - dm_table_put(table); - } - - out: - dm_put(md); - return r; -} - -/* - * Return the status of a device as a text string for each - * target. - */ -static int table_status(struct dm_ioctl *param, size_t param_size) -{ - int r; - struct mapped_device *md; - struct dm_table *table; - - md = find_device(param); - if (!md) - return -ENXIO; - - r = __dev_status(md, param); - if (r) - goto out; - - table = dm_get_table(md); - if (table) { - retrieve_status(table, param, param_size); - dm_table_put(table); - } - - out: - dm_put(md); - return r; -} - -/*----------------------------------------------------------------- - * Implementation of open/close/ioctl on the special char - * device. - *---------------------------------------------------------------*/ -static ioctl_fn lookup_ioctl(unsigned int cmd) -{ - static struct { - int cmd; - ioctl_fn fn; - } _ioctls[] = { - {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ - {DM_REMOVE_ALL_CMD, remove_all}, - {DM_LIST_DEVICES_CMD, list_devices}, - - {DM_DEV_CREATE_CMD, dev_create}, - {DM_DEV_REMOVE_CMD, dev_remove}, - {DM_DEV_RENAME_CMD, dev_rename}, - {DM_DEV_SUSPEND_CMD, dev_suspend}, - {DM_DEV_STATUS_CMD, dev_status}, - {DM_DEV_WAIT_CMD, dev_wait}, - - {DM_TABLE_LOAD_CMD, table_load}, - {DM_TABLE_CLEAR_CMD, table_clear}, - {DM_TABLE_DEPS_CMD, table_deps}, - {DM_TABLE_STATUS_CMD, table_status} - }; - - return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; -} - -/* - * As well as checking the version compatibility this always - * copies the kernel interface version out. - */ -static int check_version(unsigned int cmd, struct dm_ioctl *user) -{ - uint32_t version[3]; - int r = 0; - - if (copy_from_user(version, user->version, sizeof(version))) - return -EFAULT; - - if ((DM_VERSION_MAJOR != version[0]) || - (DM_VERSION_MINOR < version[1])) { - DMWARN("ioctl interface mismatch: " - "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", - DM_VERSION_MAJOR, DM_VERSION_MINOR, - DM_VERSION_PATCHLEVEL, - version[0], version[1], version[2], cmd); - r = -EINVAL; - } - - /* - * Fill in the kernel version. - */ - version[0] = DM_VERSION_MAJOR; - version[1] = DM_VERSION_MINOR; - version[2] = DM_VERSION_PATCHLEVEL; - if (copy_to_user(user->version, version, sizeof(version))) - return -EFAULT; - - return r; -} - -static void free_params(struct dm_ioctl *param) -{ - vfree(param); -} - -static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param) -{ - struct dm_ioctl tmp, *dmi; - - if (copy_from_user(&tmp, user, sizeof(tmp))) - return -EFAULT; - - if (tmp.data_size < sizeof(tmp)) - return -EINVAL; - - dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); - if (!dmi) - return -ENOMEM; - - if (copy_from_user(dmi, user, tmp.data_size)) { - vfree(dmi); - return -EFAULT; - } - - *param = dmi; - return 0; -} - -static int validate_params(uint cmd, struct dm_ioctl *param) -{ - /* Always clear this flag */ - param->flags &= ~DM_BUFFER_FULL_FLAG; - - /* Ignores parameters */ - if (cmd == DM_REMOVE_ALL_CMD || cmd == DM_LIST_DEVICES_CMD) - return 0; - - /* Unless creating, either name or uuid but not both */ - if (cmd != DM_DEV_CREATE_CMD) { - if ((!*param->uuid && !*param->name) || - (*param->uuid && *param->name)) { - DMWARN("one of name or uuid must be supplied, cmd(%u)", - cmd); - return -EINVAL; - } - } - - /* Ensure strings are terminated */ - param->name[DM_NAME_LEN - 1] = '\0'; - param->uuid[DM_UUID_LEN - 1] = '\0'; - - return 0; -} - -static int ctl_ioctl(struct inode *inode, struct file *file, - uint command, ulong u) -{ - int r = 0; - unsigned int cmd; - struct dm_ioctl *param; - struct dm_ioctl *user = (struct dm_ioctl *) u; - ioctl_fn fn = NULL; - size_t param_size; - - /* only root can play with this */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - if (_IOC_TYPE(command) != DM_IOCTL) - return -ENOTTY; - - cmd = _IOC_NR(command); - - /* - * Check the interface version passed in. This also - * writes out the kernel's interface version. - */ - r = check_version(cmd, user); - if (r) - return r; - - /* - * Nothing more to do for the version command. - */ - if (cmd == DM_VERSION_CMD) - return 0; - - fn = lookup_ioctl(cmd); - if (!fn) { - DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); - return -ENOTTY; - } - - /* - * Trying to avoid low memory issues when a device is - * suspended. - */ - current->flags |= PF_MEMALLOC; - - /* - * Copy the parameters into kernel space. - */ - r = copy_params(user, ¶m); - if (r) { - current->flags &= ~PF_MEMALLOC; - return r; - } - - /* - * FIXME: eventually we will remove the PF_MEMALLOC flag - * here. However the tools still do nasty things like - * 'load' while a device is suspended. - */ - - r = validate_params(cmd, param); - if (r) - goto out; - - param_size = param->data_size; - param->data_size = sizeof(*param); - r = fn(param, param_size); - - /* - * Copy the results back to userland. - */ - if (!r && copy_to_user(user, param, param->data_size)) - r = -EFAULT; - - out: - free_params(param); - current->flags &= ~PF_MEMALLOC; - return r; -} - -static struct file_operations _ctl_fops = { - .ioctl = ctl_ioctl, - .owner = THIS_MODULE, -}; - -static struct miscdevice _dm_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = DM_NAME, - .devfs_name = "mapper/control", - .fops = &_ctl_fops -}; - -/* - * Create misc character device and link to DM_DIR/control. - */ -int __init dm_interface_init(void) -{ - int r; - - r = dm_hash_init(); - if (r) - return r; - - r = misc_register(&_dm_misc); - if (r) { - DMERR("misc_register failed for control device"); - dm_hash_exit(); - return r; - } - - DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, - DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, - DM_DRIVER_EMAIL); - return 0; -} - -void dm_interface_exit(void) -{ - if (misc_deregister(&_dm_misc) < 0) - DMERR("misc_deregister failed for control device"); - - dm_hash_exit(); -} diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c --- a/drivers/md/dm-ioctl.c Sun Mar 7 18:39:37 2004 +++ b/drivers/md/dm-ioctl.c Sun Mar 7 18:39:37 2004 @@ -1,13 +1,1264 @@ /* - * Copyright (C) 2003 Sistina Software (UK) Limited. + * Copyright (C) 2001, 2002 Sistina Software (UK) Limited. * * This file is released under the GPL. */ +#include "dm.h" + +#include +#include +#include +#include +#include +#include +#include #include -#ifdef CONFIG_DM_IOCTL_V4 -#include "dm-ioctl-v4.c" -#else -#include "dm-ioctl-v1.c" -#endif +#include + +#define DM_DRIVER_EMAIL "dm@uk.sistina.com" + +/*----------------------------------------------------------------- + * The ioctl interface needs to be able to look up devices by + * name or uuid. + *---------------------------------------------------------------*/ +struct hash_cell { + struct list_head name_list; + struct list_head uuid_list; + + char *name; + char *uuid; + struct mapped_device *md; + struct dm_table *new_map; +}; + +#define NUM_BUCKETS 64 +#define MASK_BUCKETS (NUM_BUCKETS - 1) +static struct list_head _name_buckets[NUM_BUCKETS]; +static struct list_head _uuid_buckets[NUM_BUCKETS]; + +void dm_hash_remove_all(void); + +/* + * Guards access to both hash tables. + */ +static DECLARE_RWSEM(_hash_lock); + +static void init_buckets(struct list_head *buckets) +{ + unsigned int i; + + for (i = 0; i < NUM_BUCKETS; i++) + INIT_LIST_HEAD(buckets + i); +} + +int dm_hash_init(void) +{ + init_buckets(_name_buckets); + init_buckets(_uuid_buckets); + devfs_mk_dir(DM_DIR); + return 0; +} + +void dm_hash_exit(void) +{ + dm_hash_remove_all(); + devfs_remove(DM_DIR); +} + +/*----------------------------------------------------------------- + * Hash function: + * We're not really concerned with the str hash function being + * fast since it's only used by the ioctl interface. + *---------------------------------------------------------------*/ +static unsigned int hash_str(const char *str) +{ + const unsigned int hash_mult = 2654435387U; + unsigned int h = 0; + + while (*str) + h = (h + (unsigned int) *str++) * hash_mult; + + return h & MASK_BUCKETS; +} + +/*----------------------------------------------------------------- + * Code for looking up a device by name + *---------------------------------------------------------------*/ +static struct hash_cell *__get_name_cell(const char *str) +{ + struct list_head *tmp; + struct hash_cell *hc; + unsigned int h = hash_str(str); + + list_for_each (tmp, _name_buckets + h) { + hc = list_entry(tmp, struct hash_cell, name_list); + if (!strcmp(hc->name, str)) + return hc; + } + + return NULL; +} + +static struct hash_cell *__get_uuid_cell(const char *str) +{ + struct list_head *tmp; + struct hash_cell *hc; + unsigned int h = hash_str(str); + + list_for_each (tmp, _uuid_buckets + h) { + hc = list_entry(tmp, struct hash_cell, uuid_list); + if (!strcmp(hc->uuid, str)) + return hc; + } + + return NULL; +} + +/*----------------------------------------------------------------- + * Inserting, removing and renaming a device. + *---------------------------------------------------------------*/ +static inline char *kstrdup(const char *str) +{ + char *r = kmalloc(strlen(str) + 1, GFP_KERNEL); + if (r) + strcpy(r, str); + return r; +} + +static struct hash_cell *alloc_cell(const char *name, const char *uuid, + struct mapped_device *md) +{ + struct hash_cell *hc; + + hc = kmalloc(sizeof(*hc), GFP_KERNEL); + if (!hc) + return NULL; + + hc->name = kstrdup(name); + if (!hc->name) { + kfree(hc); + return NULL; + } + + if (!uuid) + hc->uuid = NULL; + + else { + hc->uuid = kstrdup(uuid); + if (!hc->uuid) { + kfree(hc->name); + kfree(hc); + return NULL; + } + } + + INIT_LIST_HEAD(&hc->name_list); + INIT_LIST_HEAD(&hc->uuid_list); + hc->md = md; + hc->new_map = NULL; + return hc; +} + +static void free_cell(struct hash_cell *hc) +{ + if (hc) { + kfree(hc->name); + kfree(hc->uuid); + kfree(hc); + } +} + +/* + * devfs stuff. + */ +static int register_with_devfs(struct hash_cell *hc) +{ + struct gendisk *disk = dm_disk(hc->md); + + devfs_mk_bdev(MKDEV(disk->major, disk->first_minor), + S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, + DM_DIR "/%s", hc->name); + return 0; +} + +static int unregister_with_devfs(struct hash_cell *hc) +{ + devfs_remove(DM_DIR"/%s", hc->name); + return 0; +} + +/* + * The kdev_t and uuid of a device can never change once it is + * initially inserted. + */ +int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) +{ + struct hash_cell *cell; + + /* + * Allocate the new cells. + */ + cell = alloc_cell(name, uuid, md); + if (!cell) + return -ENOMEM; + + /* + * Insert the cell into both hash tables. + */ + down_write(&_hash_lock); + if (__get_name_cell(name)) + goto bad; + + list_add(&cell->name_list, _name_buckets + hash_str(name)); + + if (uuid) { + if (__get_uuid_cell(uuid)) { + list_del(&cell->name_list); + goto bad; + } + list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); + } + register_with_devfs(cell); + dm_get(md); + up_write(&_hash_lock); + + return 0; + + bad: + up_write(&_hash_lock); + free_cell(cell); + return -EBUSY; +} + +void __hash_remove(struct hash_cell *hc) +{ + /* remove from the dev hash */ + list_del(&hc->uuid_list); + list_del(&hc->name_list); + unregister_with_devfs(hc); + dm_put(hc->md); + if (hc->new_map) + dm_table_put(hc->new_map); + free_cell(hc); +} + +void dm_hash_remove_all(void) +{ + int i; + struct hash_cell *hc; + struct list_head *tmp, *n; + + down_write(&_hash_lock); + for (i = 0; i < NUM_BUCKETS; i++) { + list_for_each_safe (tmp, n, _name_buckets + i) { + hc = list_entry(tmp, struct hash_cell, name_list); + __hash_remove(hc); + } + } + up_write(&_hash_lock); +} + +int dm_hash_rename(const char *old, const char *new) +{ + char *new_name, *old_name; + struct hash_cell *hc; + + /* + * duplicate new. + */ + new_name = kstrdup(new); + if (!new_name) + return -ENOMEM; + + down_write(&_hash_lock); + + /* + * Is new free ? + */ + hc = __get_name_cell(new); + if (hc) { + DMWARN("asked to rename to an already existing name %s -> %s", + old, new); + up_write(&_hash_lock); + kfree(new_name); + return -EBUSY; + } + + /* + * Is there such a device as 'old' ? + */ + hc = __get_name_cell(old); + if (!hc) { + DMWARN("asked to rename a non existent device %s -> %s", + old, new); + up_write(&_hash_lock); + kfree(new_name); + return -ENXIO; + } + + /* + * rename and move the name cell. + */ + unregister_with_devfs(hc); + + list_del(&hc->name_list); + old_name = hc->name; + hc->name = new_name; + list_add(&hc->name_list, _name_buckets + hash_str(new_name)); + + /* rename the device node in devfs */ + register_with_devfs(hc); + + up_write(&_hash_lock); + kfree(old_name); + return 0; +} + +/*----------------------------------------------------------------- + * Implementation of the ioctl commands + *---------------------------------------------------------------*/ +/* + * All the ioctl commands get dispatched to functions with this + * prototype. + */ +typedef int (*ioctl_fn)(struct dm_ioctl *param, size_t param_size); + +static int remove_all(struct dm_ioctl *param, size_t param_size) +{ + dm_hash_remove_all(); + param->data_size = 0; + return 0; +} + +/* + * Round up the ptr to an 8-byte boundary. + */ +#define ALIGN_MASK 7 +static inline void *align_ptr(void *ptr) +{ + return (void *) (((size_t) (ptr + ALIGN_MASK)) & ~ALIGN_MASK); +} + +/* + * Retrieves the data payload buffer from an already allocated + * struct dm_ioctl. + */ +static void *get_result_buffer(struct dm_ioctl *param, size_t param_size, + size_t *len) +{ + param->data_start = align_ptr(param + 1) - (void *) param; + + if (param->data_start < param_size) + *len = param_size - param->data_start; + else + *len = 0; + + return ((void *) param) + param->data_start; +} + +static int list_devices(struct dm_ioctl *param, size_t param_size) +{ + unsigned int i; + struct hash_cell *hc; + size_t len, needed = 0; + struct gendisk *disk; + struct dm_name_list *nl, *old_nl = NULL; + + down_write(&_hash_lock); + + /* + * Loop through all the devices working out how much + * space we need. + */ + for (i = 0; i < NUM_BUCKETS; i++) { + list_for_each_entry (hc, _name_buckets + i, name_list) { + needed += sizeof(struct dm_name_list); + needed += strlen(hc->name); + needed += ALIGN_MASK; + } + } + + /* + * Grab our output buffer. + */ + nl = get_result_buffer(param, param_size, &len); + if (len < needed) { + param->flags |= DM_BUFFER_FULL_FLAG; + goto out; + } + param->data_size = param->data_start + needed; + + nl->dev = 0; /* Flags no data */ + + /* + * Now loop through filling out the names. + */ + for (i = 0; i < NUM_BUCKETS; i++) { + list_for_each_entry (hc, _name_buckets + i, name_list) { + if (old_nl) + old_nl->next = (uint32_t) ((void *) nl - + (void *) old_nl); + disk = dm_disk(hc->md); + nl->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); + nl->next = 0; + strcpy(nl->name, hc->name); + + old_nl = nl; + nl = align_ptr(((void *) ++nl) + strlen(hc->name) + 1); + } + } + + out: + up_write(&_hash_lock); + return 0; +} + +static int check_name(const char *name) +{ + if (strchr(name, '/')) { + DMWARN("invalid device name"); + return -EINVAL; + } + + return 0; +} + +/* + * Fills in a dm_ioctl structure, ready for sending back to + * userland. + */ +static int __dev_status(struct mapped_device *md, struct dm_ioctl *param) +{ + struct gendisk *disk = dm_disk(md); + struct dm_table *table; + struct block_device *bdev; + + param->flags &= ~(DM_SUSPEND_FLAG | DM_READONLY_FLAG | + DM_ACTIVE_PRESENT_FLAG); + + if (dm_suspended(md)) + param->flags |= DM_SUSPEND_FLAG; + + bdev = bdget_disk(disk, 0); + if (!bdev) + return -ENXIO; + + param->dev = huge_encode_dev(MKDEV(disk->major, disk->first_minor)); + + /* + * Yes, this will be out of date by the time it gets back + * to userland, but it is still very useful ofr + * debugging. + */ + param->open_count = bdev->bd_openers; + bdput(bdev); + + if (disk->policy) + param->flags |= DM_READONLY_FLAG; + + param->event_nr = dm_get_event_nr(md); + + table = dm_get_table(md); + if (table) { + param->flags |= DM_ACTIVE_PRESENT_FLAG; + param->target_count = dm_table_get_num_targets(table); + dm_table_put(table); + } else + param->target_count = 0; + + return 0; +} + +static int dev_create(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct mapped_device *md; + + r = check_name(param->name); + if (r) + return r; + + if (param->flags & DM_PERSISTENT_DEV_FLAG) + r = dm_create_with_minor(MINOR(huge_decode_dev(param->dev)), &md); + else + r = dm_create(&md); + + if (r) + return r; + + r = dm_hash_insert(param->name, *param->uuid ? param->uuid : NULL, md); + if (r) { + dm_put(md); + return r; + } + + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + + r = __dev_status(md, param); + dm_put(md); + + return r; +} + +/* + * Always use UUID for lookups if it's present, otherwise use name. + */ +static inline struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) +{ + return *param->uuid ? + __get_uuid_cell(param->uuid) : __get_name_cell(param->name); +} + +static inline struct mapped_device *find_device(struct dm_ioctl *param) +{ + struct hash_cell *hc; + struct mapped_device *md = NULL; + + down_read(&_hash_lock); + hc = __find_device_hash_cell(param); + if (hc) { + md = hc->md; + + /* + * Sneakily write in both the name and the uuid + * while we have the cell. + */ + strncpy(param->name, hc->name, sizeof(param->name)); + if (hc->uuid) + strncpy(param->uuid, hc->uuid, sizeof(param->uuid)-1); + else + param->uuid[0] = '\0'; + + if (hc->new_map) + param->flags |= DM_INACTIVE_PRESENT_FLAG; + else + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + + dm_get(md); + } + up_read(&_hash_lock); + + return md; +} + +static int dev_remove(struct dm_ioctl *param, size_t param_size) +{ + struct hash_cell *hc; + + down_write(&_hash_lock); + hc = __find_device_hash_cell(param); + + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); + up_write(&_hash_lock); + return -ENXIO; + } + + __hash_remove(hc); + up_write(&_hash_lock); + param->data_size = 0; + return 0; +} + +/* + * Check a string doesn't overrun the chunk of + * memory we copied from userland. + */ +static int invalid_str(char *str, void *end) +{ + while ((void *) str < end) + if (!*str++) + return 0; + + return -EINVAL; +} + +static int dev_rename(struct dm_ioctl *param, size_t param_size) +{ + int r; + char *new_name = (char *) param + param->data_start; + + if (new_name < (char *) (param + 1) || + invalid_str(new_name, (void *) param + param_size)) { + DMWARN("Invalid new logical volume name supplied."); + return -EINVAL; + } + + r = check_name(new_name); + if (r) + return r; + + param->data_size = 0; + return dm_hash_rename(param->name, new_name); +} + +static int do_suspend(struct dm_ioctl *param) +{ + int r = 0; + struct mapped_device *md; + + md = find_device(param); + if (!md) + return -ENXIO; + + if (!dm_suspended(md)) + r = dm_suspend(md); + + if (!r) + r = __dev_status(md, param); + + dm_put(md); + return r; +} + +static int do_resume(struct dm_ioctl *param) +{ + int r = 0; + struct hash_cell *hc; + struct mapped_device *md; + struct dm_table *new_map; + + down_write(&_hash_lock); + + hc = __find_device_hash_cell(param); + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); + up_write(&_hash_lock); + return -ENXIO; + } + + md = hc->md; + dm_get(md); + + new_map = hc->new_map; + hc->new_map = NULL; + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + + up_write(&_hash_lock); + + /* Do we need to load a new map ? */ + if (new_map) { + /* Suspend if it isn't already suspended */ + if (!dm_suspended(md)) + dm_suspend(md); + + r = dm_swap_table(md, new_map); + if (r) { + dm_put(md); + dm_table_put(new_map); + return r; + } + + if (dm_table_get_mode(new_map) & FMODE_WRITE) + set_disk_ro(dm_disk(md), 0); + else + set_disk_ro(dm_disk(md), 1); + + dm_table_put(new_map); + } + + if (dm_suspended(md)) + r = dm_resume(md); + + if (!r) + r = __dev_status(md, param); + + dm_put(md); + return r; +} + +/* + * Set or unset the suspension state of a device. + * If the device already is in the requested state we just return its status. + */ +static int dev_suspend(struct dm_ioctl *param, size_t param_size) +{ + if (param->flags & DM_SUSPEND_FLAG) + return do_suspend(param); + + return do_resume(param); +} + +/* + * Copies device info back to user space, used by + * the create and info ioctls. + */ +static int dev_status(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct mapped_device *md; + + md = find_device(param); + if (!md) + return -ENXIO; + + r = __dev_status(md, param); + dm_put(md); + return r; +} + +/* + * Build up the status struct for each target + */ +static void retrieve_status(struct dm_table *table, + struct dm_ioctl *param, size_t param_size) +{ + unsigned int i, num_targets; + struct dm_target_spec *spec; + char *outbuf, *outptr; + status_type_t type; + size_t remaining, len, used = 0; + + outptr = outbuf = get_result_buffer(param, param_size, &len); + + if (param->flags & DM_STATUS_TABLE_FLAG) + type = STATUSTYPE_TABLE; + else + type = STATUSTYPE_INFO; + + /* Get all the target info */ + num_targets = dm_table_get_num_targets(table); + for (i = 0; i < num_targets; i++) { + struct dm_target *ti = dm_table_get_target(table, i); + + remaining = len - (outptr - outbuf); + if (remaining < sizeof(struct dm_target_spec)) { + param->flags |= DM_BUFFER_FULL_FLAG; + break; + } + + spec = (struct dm_target_spec *) outptr; + + spec->status = 0; + spec->sector_start = ti->begin; + spec->length = ti->len; + strncpy(spec->target_type, ti->type->name, + sizeof(spec->target_type)); + + outptr += sizeof(struct dm_target_spec); + remaining = len - (outptr - outbuf); + + /* Get the status/table string from the target driver */ + if (ti->type->status) { + if (ti->type->status(ti, type, outptr, remaining)) { + param->flags |= DM_BUFFER_FULL_FLAG; + break; + } + } else + outptr[0] = '\0'; + + outptr += strlen(outptr) + 1; + used = param->data_start + (outptr - outbuf); + + align_ptr(outptr); + spec->next = outptr - outbuf; + } + + if (used) + param->data_size = used; + + param->target_count = num_targets; +} + +/* + * Wait for a device to report an event + */ +static int dev_wait(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct mapped_device *md; + struct dm_table *table; + DECLARE_WAITQUEUE(wq, current); + + md = find_device(param); + if (!md) + return -ENXIO; + + /* + * Wait for a notification event + */ + set_current_state(TASK_INTERRUPTIBLE); + if (!dm_add_wait_queue(md, &wq, param->event_nr)) { + schedule(); + dm_remove_wait_queue(md, &wq); + } + set_current_state(TASK_RUNNING); + + /* + * The userland program is going to want to know what + * changed to trigger the event, so we may as well tell + * him and save an ioctl. + */ + r = __dev_status(md, param); + if (r) + goto out; + + table = dm_get_table(md); + if (table) { + retrieve_status(table, param, param_size); + dm_table_put(table); + } + + out: + dm_put(md); + return r; +} + +static inline int get_mode(struct dm_ioctl *param) +{ + int mode = FMODE_READ | FMODE_WRITE; + + if (param->flags & DM_READONLY_FLAG) + mode = FMODE_READ; + + return mode; +} + +static int next_target(struct dm_target_spec *last, uint32_t next, void *end, + struct dm_target_spec **spec, char **target_params) +{ + *spec = (struct dm_target_spec *) ((unsigned char *) last + next); + *target_params = (char *) (*spec + 1); + + if (*spec < (last + 1)) + return -EINVAL; + + return invalid_str(*target_params, end); +} + +static int populate_table(struct dm_table *table, + struct dm_ioctl *param, size_t param_size) +{ + int r; + unsigned int i = 0; + struct dm_target_spec *spec = (struct dm_target_spec *) param; + uint32_t next = param->data_start; + void *end = (void *) param + param_size; + char *target_params; + + if (!param->target_count) { + DMWARN("populate_table: no targets specified"); + return -EINVAL; + } + + for (i = 0; i < param->target_count; i++) { + + r = next_target(spec, next, end, &spec, &target_params); + if (r) { + DMWARN("unable to find target"); + return r; + } + + r = dm_table_add_target(table, spec->target_type, + (sector_t) spec->sector_start, + (sector_t) spec->length, + target_params); + if (r) { + DMWARN("error adding target to table"); + return r; + } + + next = spec->next; + } + + return dm_table_complete(table); +} + +static int table_load(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct hash_cell *hc; + struct dm_table *t; + + r = dm_table_create(&t, get_mode(param), param->target_count); + if (r) + return r; + + r = populate_table(t, param, param_size); + if (r) { + dm_table_put(t); + return r; + } + + down_write(&_hash_lock); + hc = __find_device_hash_cell(param); + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); + up_write(&_hash_lock); + return -ENXIO; + } + + if (hc->new_map) + dm_table_put(hc->new_map); + hc->new_map = t; + param->flags |= DM_INACTIVE_PRESENT_FLAG; + + r = __dev_status(hc->md, param); + up_write(&_hash_lock); + return r; +} + +static int table_clear(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct hash_cell *hc; + + down_write(&_hash_lock); + + hc = __find_device_hash_cell(param); + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); + up_write(&_hash_lock); + return -ENXIO; + } + + if (hc->new_map) { + dm_table_put(hc->new_map); + hc->new_map = NULL; + } + + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + + r = __dev_status(hc->md, param); + up_write(&_hash_lock); + return r; +} + +/* + * Retrieves a list of devices used by a particular dm device. + */ +static void retrieve_deps(struct dm_table *table, + struct dm_ioctl *param, size_t param_size) +{ + unsigned int count = 0; + struct list_head *tmp; + size_t len, needed; + struct dm_target_deps *deps; + + deps = get_result_buffer(param, param_size, &len); + + /* + * Count the devices. + */ + list_for_each(tmp, dm_table_get_devices(table)) + count++; + + /* + * Check we have enough space. + */ + needed = sizeof(*deps) + (sizeof(*deps->dev) * count); + if (len < needed) { + param->flags |= DM_BUFFER_FULL_FLAG; + return; + } + + /* + * Fill in the devices. + */ + deps->count = count; + count = 0; + list_for_each(tmp, dm_table_get_devices(table)) { + struct dm_dev *dd = list_entry(tmp, struct dm_dev, list); + deps->dev[count++] = huge_encode_dev(dd->bdev->bd_dev); + } + + param->data_size = param->data_start + needed; +} + +static int table_deps(struct dm_ioctl *param, size_t param_size) +{ + int r = 0; + struct mapped_device *md; + struct dm_table *table; + + md = find_device(param); + if (!md) + return -ENXIO; + + r = __dev_status(md, param); + if (r) + goto out; + + table = dm_get_table(md); + if (table) { + retrieve_deps(table, param, param_size); + dm_table_put(table); + } + + out: + dm_put(md); + return r; +} + +/* + * Return the status of a device as a text string for each + * target. + */ +static int table_status(struct dm_ioctl *param, size_t param_size) +{ + int r; + struct mapped_device *md; + struct dm_table *table; + + md = find_device(param); + if (!md) + return -ENXIO; + + r = __dev_status(md, param); + if (r) + goto out; + + table = dm_get_table(md); + if (table) { + retrieve_status(table, param, param_size); + dm_table_put(table); + } + + out: + dm_put(md); + return r; +} + +/*----------------------------------------------------------------- + * Implementation of open/close/ioctl on the special char + * device. + *---------------------------------------------------------------*/ +static ioctl_fn lookup_ioctl(unsigned int cmd) +{ + static struct { + int cmd; + ioctl_fn fn; + } _ioctls[] = { + {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */ + {DM_REMOVE_ALL_CMD, remove_all}, + {DM_LIST_DEVICES_CMD, list_devices}, + + {DM_DEV_CREATE_CMD, dev_create}, + {DM_DEV_REMOVE_CMD, dev_remove}, + {DM_DEV_RENAME_CMD, dev_rename}, + {DM_DEV_SUSPEND_CMD, dev_suspend}, + {DM_DEV_STATUS_CMD, dev_status}, + {DM_DEV_WAIT_CMD, dev_wait}, + + {DM_TABLE_LOAD_CMD, table_load}, + {DM_TABLE_CLEAR_CMD, table_clear}, + {DM_TABLE_DEPS_CMD, table_deps}, + {DM_TABLE_STATUS_CMD, table_status} + }; + + return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; +} + +/* + * As well as checking the version compatibility this always + * copies the kernel interface version out. + */ +static int check_version(unsigned int cmd, struct dm_ioctl *user) +{ + uint32_t version[3]; + int r = 0; + + if (copy_from_user(version, user->version, sizeof(version))) + return -EFAULT; + + if ((DM_VERSION_MAJOR != version[0]) || + (DM_VERSION_MINOR < version[1])) { + DMWARN("ioctl interface mismatch: " + "kernel(%u.%u.%u), user(%u.%u.%u), cmd(%d)", + DM_VERSION_MAJOR, DM_VERSION_MINOR, + DM_VERSION_PATCHLEVEL, + version[0], version[1], version[2], cmd); + r = -EINVAL; + } + + /* + * Fill in the kernel version. + */ + version[0] = DM_VERSION_MAJOR; + version[1] = DM_VERSION_MINOR; + version[2] = DM_VERSION_PATCHLEVEL; + if (copy_to_user(user->version, version, sizeof(version))) + return -EFAULT; + + return r; +} + +static void free_params(struct dm_ioctl *param) +{ + vfree(param); +} + +static int copy_params(struct dm_ioctl *user, struct dm_ioctl **param) +{ + struct dm_ioctl tmp, *dmi; + + if (copy_from_user(&tmp, user, sizeof(tmp))) + return -EFAULT; + + if (tmp.data_size < sizeof(tmp)) + return -EINVAL; + + dmi = (struct dm_ioctl *) vmalloc(tmp.data_size); + if (!dmi) + return -ENOMEM; + + if (copy_from_user(dmi, user, tmp.data_size)) { + vfree(dmi); + return -EFAULT; + } + + *param = dmi; + return 0; +} + +static int validate_params(uint cmd, struct dm_ioctl *param) +{ + /* Always clear this flag */ + param->flags &= ~DM_BUFFER_FULL_FLAG; + + /* Ignores parameters */ + if (cmd == DM_REMOVE_ALL_CMD || cmd == DM_LIST_DEVICES_CMD) + return 0; + + /* Unless creating, either name or uuid but not both */ + if (cmd != DM_DEV_CREATE_CMD) { + if ((!*param->uuid && !*param->name) || + (*param->uuid && *param->name)) { + DMWARN("one of name or uuid must be supplied, cmd(%u)", + cmd); + return -EINVAL; + } + } + + /* Ensure strings are terminated */ + param->name[DM_NAME_LEN - 1] = '\0'; + param->uuid[DM_UUID_LEN - 1] = '\0'; + + return 0; +} + +static int ctl_ioctl(struct inode *inode, struct file *file, + uint command, ulong u) +{ + int r = 0; + unsigned int cmd; + struct dm_ioctl *param; + struct dm_ioctl *user = (struct dm_ioctl *) u; + ioctl_fn fn = NULL; + size_t param_size; + + /* only root can play with this */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (_IOC_TYPE(command) != DM_IOCTL) + return -ENOTTY; + + cmd = _IOC_NR(command); + + /* + * Check the interface version passed in. This also + * writes out the kernel's interface version. + */ + r = check_version(cmd, user); + if (r) + return r; + + /* + * Nothing more to do for the version command. + */ + if (cmd == DM_VERSION_CMD) + return 0; + + fn = lookup_ioctl(cmd); + if (!fn) { + DMWARN("dm_ctl_ioctl: unknown command 0x%x", command); + return -ENOTTY; + } + + /* + * Trying to avoid low memory issues when a device is + * suspended. + */ + current->flags |= PF_MEMALLOC; + + /* + * Copy the parameters into kernel space. + */ + r = copy_params(user, ¶m); + if (r) { + current->flags &= ~PF_MEMALLOC; + return r; + } + + /* + * FIXME: eventually we will remove the PF_MEMALLOC flag + * here. However the tools still do nasty things like + * 'load' while a device is suspended. + */ + + r = validate_params(cmd, param); + if (r) + goto out; + + param_size = param->data_size; + param->data_size = sizeof(*param); + r = fn(param, param_size); + + /* + * Copy the results back to userland. + */ + if (!r && copy_to_user(user, param, param->data_size)) + r = -EFAULT; + + out: + free_params(param); + current->flags &= ~PF_MEMALLOC; + return r; +} + +static struct file_operations _ctl_fops = { + .ioctl = ctl_ioctl, + .owner = THIS_MODULE, +}; + +static struct miscdevice _dm_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = DM_NAME, + .devfs_name = "mapper/control", + .fops = &_ctl_fops +}; + +/* + * Create misc character device and link to DM_DIR/control. + */ +int __init dm_interface_init(void) +{ + int r; + + r = dm_hash_init(); + if (r) + return r; + + r = misc_register(&_dm_misc); + if (r) { + DMERR("misc_register failed for control device"); + dm_hash_exit(); + return r; + } + + DMINFO("%d.%d.%d%s initialised: %s", DM_VERSION_MAJOR, + DM_VERSION_MINOR, DM_VERSION_PATCHLEVEL, DM_VERSION_EXTRA, + DM_DRIVER_EMAIL); + return 0; +} + +void dm_interface_exit(void) +{ + if (misc_deregister(&_dm_misc) < 0) + DMERR("misc_deregister failed for control device"); + + dm_hash_exit(); +} diff -Nru a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c --- a/drivers/media/video/v4l1-compat.c Sun Mar 7 18:39:37 2004 +++ b/drivers/media/video/v4l1-compat.c Sun Mar 7 18:39:37 2004 @@ -503,10 +503,11 @@ int *on = arg; if (0 == *on) { + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* dirty hack time. But v4l1 has no STREAMOFF * equivalent in the API, and this one at * least comes close ... */ - drv(inode, file, VIDIOC_STREAMOFF, NULL); + drv(inode, file, VIDIOC_STREAMOFF, &type); } err = drv(inode, file, VIDIOC_OVERLAY, arg); if (err < 0) @@ -857,6 +858,7 @@ case VIDIOCMCAPTURE: /* capture a frame */ { struct video_mmap *mm = arg; + enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); memset(&buf2,0,sizeof(buf2)); @@ -897,7 +899,7 @@ dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err); break; } - err = drv(inode, file, VIDIOC_STREAMON, NULL); + err = drv(inode, file, VIDIOC_STREAMON, &type); if (err < 0) dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err); break; diff -Nru a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig --- a/drivers/message/i2o/Kconfig Sun Mar 7 18:39:36 2004 +++ b/drivers/message/i2o/Kconfig Sun Mar 7 18:39:36 2004 @@ -39,7 +39,10 @@ depends on I2O help Include support for the I2O Block OSM. The Block OSM presents disk - and other structured block devices to the operating system. + and other structured block devices to the operating system. If you + are using an RAID controller, you could access the array only by + the Block OSM driver. But it is possible to access the single disks + by the SCSI OSM driver, for example to monitor the disks. To compile this support as a module, choose M here: the module will be called i2o_block. @@ -50,7 +53,8 @@ help Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel I2O controller. You can use both the SCSI and Block OSM together if - you wish. + you wish. To access a RAID array, you must use the Block OSM driver. + But you could use the SCSI OSM driver to monitor the single disks. To compile this support as a module, choose M here: the module will be called i2o_scsi. diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c --- a/drivers/message/i2o/i2o_block.c Sun Mar 7 18:39:37 2004 +++ b/drivers/message/i2o/i2o_block.c Sun Mar 7 18:39:37 2004 @@ -50,9 +50,11 @@ * Properly attach/detach I2O gendisk structure from the system * gendisk list. The I2O block devices now appear in * /proc/partitions. + * Markus Lidel : + * Minor bugfixes for 2.6. * - * To do: - * Serial number scanning to find duplicates for FC multipathing + * To do: + * Serial number scanning to find duplicates for FC multipathing */ #include @@ -109,25 +111,6 @@ I2O_EVT_IND_BSA_SCSI_SMART ) -/* - * I2O Block Error Codes - should be in a header file really... - */ -#define I2O_BSA_DSC_SUCCESS 0x0000 -#define I2O_BSA_DSC_MEDIA_ERROR 0x0001 -#define I2O_BSA_DSC_ACCESS_ERROR 0x0002 -#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003 -#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004 -#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005 -#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006 -#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007 -#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008 -#define I2O_BSA_DSC_BUS_FAILURE 0x0009 -#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A -#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B -#define I2O_BSA_DSC_DEVICE_RESET 0x000C -#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D -#define I2O_BSA_DSC_TIMEOUT 0x000E - #define I2O_LOCK(unit) (i2ob_dev[(unit)].req_queue->queue_lock) /* @@ -1091,6 +1074,28 @@ d->lct_data.tid, unit); /* + * If this is the first I2O block device found on this IOP, + * we need to initialize all the queue data structures + * before any I/O can be performed. If it fails, this + * device is useless. + */ + if(!i2ob_queues[unit]) { + if(i2ob_init_iop(unit)) + return 1; + } + + /* + * This will save one level of lookup/indirection in critical + * code so that we can directly get the queue ptr from the + * device instead of having to go the IOP data structure. + */ + dev->req_queue = i2ob_queues[unit]->req_queue; + + /* initialize gendik structure */ + i2ob_disk[unit>>4]->private_data = dev; + i2ob_disk[unit>>4]->queue = dev->req_queue; + + /* * Ask for the current media data. If that isn't supported * then we ask for the device capacity data */ @@ -1148,6 +1153,7 @@ } strcpy(d->dev_name, i2ob_disk[unit>>4]->disk_name); + strcpy(i2ob_disk[unit>>4]->devfs_name, i2ob_disk[unit>>4]->disk_name); printk(KERN_INFO "%s: Max segments %d, queue depth %d, byte limit %d.\n", d->dev_name, i2ob_dev[unit].max_segments, i2ob_dev[unit].depth, i2ob_max_sectors[unit]<<9); @@ -1193,28 +1199,6 @@ printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n", d->dev_name, i2ob_max_sectors[unit]); - /* - * If this is the first I2O block device found on this IOP, - * we need to initialize all the queue data structures - * before any I/O can be performed. If it fails, this - * device is useless. - */ - if(!i2ob_queues[c->unit]) { - if(i2ob_init_iop(c->unit)) - return 1; - } - - /* - * This will save one level of lookup/indirection in critical - * code so that we can directly get the queue ptr from the - * device instead of having to go the IOP data structure. - */ - dev->req_queue = i2ob_queues[c->unit]->req_queue; - - /* Register a size before we register for events - otherwise we - might miss and overwrite an event */ - set_capacity(i2ob_disk[unit>>4], size>>9); - /* * Register for the events we're interested in and that the * device actually supports. @@ -1251,6 +1235,7 @@ i2ob_queues[unit]->i2ob_qhead = &i2ob_queues[unit]->request_queue[0]; atomic_set(&i2ob_queues[unit]->queue_depth, 0); + i2ob_queues[unit]->lock = SPIN_LOCK_UNLOCKED; i2ob_queues[unit]->req_queue = blk_init_queue(i2ob_request, &i2ob_queues[unit]->lock); if (!i2ob_queues[unit]->req_queue) { kfree(i2ob_queues[unit]); @@ -1336,6 +1321,8 @@ continue; } + i2o_release_device(d, &i2o_block_handler); + if(scan_unit>4); } - i2o_release_device(d, &i2o_block_handler); } i2o_unlock_controller(c); } @@ -1699,9 +1685,9 @@ if(evt_running) { printk(KERN_INFO "Killing I2O block threads..."); - i = kill_proc(evt_pid, SIGTERM, 1); + i = kill_proc(evt_pid, SIGKILL, 1); if(!i) { - printk("waiting..."); + printk("waiting...\n"); } /* Be sure it died */ wait_for_completion(&i2ob_thread_dead); diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c --- a/drivers/message/i2o/i2o_core.c Sun Mar 7 18:39:37 2004 +++ b/drivers/message/i2o/i2o_core.c Sun Mar 7 18:39:37 2004 @@ -13,15 +13,16 @@ * A lot of the I2O message side code from this is taken from the * Red Creek RCPCI45 adapter driver by Red Creek Communications * - * Fixes by: - * Philipp Rumpf - * Juha Sievänen - * Auvo Häkkinen - * Deepak Saxena - * Boji T Kannanthanam - * - * Ported to Linux 2.5 by - * Alan Cox + * Fixes/additions: + * Philipp Rumpf + * Juha Sievänen + * Auvo Häkkinen + * Deepak Saxena + * Boji T Kannanthanam + * Alan Cox : + * Ported to Linux 2.5. + * Markus Lidel : + * Minor fixes for 2.6. * */ @@ -502,6 +503,7 @@ c->unit = i; c->page_frame = NULL; c->hrt = NULL; + c->hrt_len = 0; c->lct = NULL; c->status_block = NULL; sprintf(c->name, "i2o/iop%d", i); @@ -564,7 +566,7 @@ * If this is shutdown time, the thread's already been killed */ if(c->lct_running) { - stat = kill_proc(c->lct_pid, SIGTERM, 1); + stat = kill_proc(c->lct_pid, SIGKILL, 1); if(!stat) { int count = 10 * 100; while(c->lct_running && --count) { @@ -1861,31 +1863,36 @@ { u32 msg[6]; int ret, size = sizeof(i2o_hrt); + int loops = 3; /* we only try 3 times to get the HRT, this should be + more then enough. Worst case should be 2 times.*/ /* First read just the header to figure out the real size */ do { + /* first we allocate the memory for the HRT */ if (c->hrt == NULL) { c->hrt=pci_alloc_consistent(c->pdev, size, &c->hrt_phys); if (c->hrt == NULL) { printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", c->name); return -ENOMEM; } + c->hrt_len = size; } msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4; msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID; msg[3]= 0; - msg[4]= (0xD0000000 | size); /* Simple transaction */ + msg[4]= (0xD0000000 | c->hrt_len); /* Simple transaction */ msg[5]= c->hrt_phys; /* Dump it here */ - ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL, c->hrt_phys, 0, size, 0); + ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL, c->hrt_phys, 0, c->hrt_len, 0); if(ret == -ETIMEDOUT) { /* The HRT block we used is in limbo somewhere. When the iop wakes up we will recover it */ c->hrt = NULL; + c->hrt_len = 0; return ret; } @@ -1896,13 +1903,20 @@ return ret; } - if (c->hrt->num_entries * c->hrt->entry_len << 2 > size) { - int new_size = c->hrt->num_entries * c->hrt->entry_len << 2; - pci_free_consistent(c->pdev, size, c->hrt, c->hrt_phys); - size = new_size; + if (c->hrt->num_entries * c->hrt->entry_len << 2 > c->hrt_len) { + size = c->hrt->num_entries * c->hrt->entry_len << 2; + pci_free_consistent(c->pdev, c->hrt_len, c->hrt, c->hrt_phys); + c->hrt_len = 0; c->hrt = NULL; } - } while (c->hrt == NULL); + loops --; + } while (c->hrt == NULL && loops > 0); + + if(c->hrt == NULL) + { + printk(KERN_ERR "%s: Unable to get HRT after three tries, giving up\n", c->name); + return -1; + } i2o_parse_hrt(c); // just for debugging @@ -3628,8 +3642,6 @@ return 0; } -static int dpt; - /** * i2o_pci_scan - Scan the pci bus for controllers * @@ -3654,14 +3666,7 @@ { if((dev->class>>8)!=PCI_CLASS_INTELLIGENT_I2O) continue; - if(dev->vendor == PCI_VENDOR_ID_DPT && !dpt) - { - if(dev->device == 0xA501 || dev->device == 0xA511) - { - printk(KERN_INFO "i2o: Skipping Adaptec/DPT I2O raid with preferred native driver.\n"); - continue; - } - } + if((dev->class&0xFF)>1) { printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n"); @@ -3735,22 +3740,19 @@ */ if(evt_running) { printk("Terminating i2o threads..."); - stat = kill_proc(evt_pid, SIGTERM, 1); + stat = kill_proc(evt_pid, SIGKILL, 1); if(!stat) { - printk("waiting..."); + printk("waiting...\n"); wait_for_completion(&evt_dead); } printk("done.\n"); } i2o_remove_handler(&i2o_core_handler); - unregister_reboot_notifier(&i2o_reboot_notifier); } module_init(i2o_core_init); module_exit(i2o_core_exit); -MODULE_PARM(dpt, "i"); -MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o"); MODULE_PARM(verbose, "i"); MODULE_PARM_DESC(verbose, "Verbose diagnostics"); diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c --- a/drivers/message/i2o/i2o_scsi.c Sun Mar 7 18:39:38 2004 +++ b/drivers/message/i2o/i2o_scsi.c Sun Mar 7 18:39:38 2004 @@ -29,12 +29,15 @@ * In general the firmware wants to help. Where its help isn't performance * useful we just ignore the aid. Its not worth the code in truth. * - * Fixes: - * Steve Ralston : Scatter gather now works + * Fixes/additions: + * Steve Ralston: + * Scatter gather now works + * Markus Lidel : + * Minor fixes for 2.6. * - * To Do - * 64bit cleanups - * Fix the resource management problems. + * To Do: + * 64bit cleanups + * Fix the resource management problems. */ @@ -66,7 +69,13 @@ #define VERSION_STRING "Version 0.1.2" -#define dprintk(x) +//#define DRIVERDEBUG + +#ifdef DRIVERDEBUG +#define dprintk(s, args...) printk(s, ## args) +#else +#define dprintk(s, args...) +#endif #define I2O_SCSI_CAN_QUEUE 4 #define MAXHOSTS 32 @@ -252,15 +261,15 @@ as=(u8)le32_to_cpu(m[4]>>8); st=(u8)le32_to_cpu(m[4]>>24); - dprintk(("i2o got a scsi reply %08X: ", m[0])); - dprintk(("m[2]=%08X: ", m[2])); - dprintk(("m[4]=%08X\n", m[4])); + dprintk(KERN_INFO "i2o got a scsi reply %08X: ", m[0]); + dprintk(KERN_INFO "m[2]=%08X: ", m[2]); + dprintk(KERN_INFO "m[4]=%08X\n", m[4]); if(m[2]&0x80000000) { if(m[2]&0x40000000) { - dprintk(("Event.\n")); + dprintk(KERN_INFO "Event.\n"); lun_done=1; return; } @@ -280,12 +289,12 @@ if(current_command==NULL) { if(st) - dprintk(("SCSI abort: %08X", m[4])); - dprintk(("SCSI abort completed.\n")); + dprintk(KERN_WARNING "SCSI abort: %08X", m[4]); + dprintk(KERN_INFO "SCSI abort completed.\n"); return; } - dprintk(("Completed %ld\n", current_command->serial_number)); + dprintk(KERN_INFO "Completed %ld\n", current_command->serial_number); atomic_dec(&queue_depth); @@ -308,7 +317,7 @@ { /* An error has occurred */ - dprintk((KERN_DEBUG "SCSI error %08X", m[4])); + dprintk(KERN_WARNING "SCSI error %08X", m[4]); if (as == 0x0E) /* SCSI Reset */ @@ -368,7 +377,7 @@ *lun=reply[1]; - dprintk(("SCSI (%d,%d)\n", *target, *lun)); + dprintk(KERN_INFO "SCSI (%d,%d)\n", *target, *lun); return 0; } @@ -401,8 +410,8 @@ for(unit=c->devices;unit!=NULL;unit=unit->next) { - dprintk(("Class %03X, parent %d, want %d.\n", - unit->lct_data.class_id, unit->lct_data.parent_tid, d->lct_data.tid)); + dprintk(KERN_INFO "Class %03X, parent %d, want %d.\n", + unit->lct_data.class_id, unit->lct_data.parent_tid, d->lct_data.tid); /* Only look at scsi and fc devices */ if ( (unit->lct_data.class_id != I2O_CLASS_SCSI_PERIPHERAL) @@ -411,19 +420,19 @@ continue; /* On our bus ? */ - dprintk(("Found a disk (%d).\n", unit->lct_data.tid)); + dprintk(KERN_INFO "Found a disk (%d).\n", unit->lct_data.tid); if ((unit->lct_data.parent_tid == d->lct_data.tid) || (unit->lct_data.parent_tid == d->lct_data.parent_tid) ) { u16 limit; - dprintk(("Its ours.\n")); + dprintk(KERN_INFO "Its ours.\n"); if(i2o_find_lun(c, unit, &target, &lun)==-1) { printk(KERN_ERR "i2o_scsi: Unable to get lun for tid %d.\n", unit->lct_data.tid); continue; } - dprintk(("Found disk %d %d.\n", target, lun)); + dprintk(KERN_INFO "Found disk %d %d.\n", target, lun); h->task[target][lun]=unit->lct_data.tid; h->tagclock[target][lun]=jiffies; @@ -439,8 +448,8 @@ shpnt->sg_tablesize = limit; - dprintk(("i2o_scsi: set scatter-gather to %d.\n", - shpnt->sg_tablesize)); + dprintk(KERN_INFO "i2o_scsi: set scatter-gather to %d.\n", + shpnt->sg_tablesize); } } } @@ -558,6 +567,9 @@ del_timer(&retry_timer); i2o_remove_handler(&i2o_scsi_handler); } + + scsi_unregister(host); + return 0; } @@ -624,7 +636,7 @@ tid = hostdata->task[SCpnt->device->id][SCpnt->device->lun]; - dprintk(("qcmd: Tid = %d\n", tid)); + dprintk(KERN_INFO "qcmd: Tid = %d\n", tid); current_command = SCpnt; /* set current command */ current_command->scsi_done = done; /* set ptr to done function */ @@ -641,7 +653,7 @@ return 0; } - dprintk(("Real scsi messages.\n")); + dprintk(KERN_INFO "Real scsi messages.\n"); /* * Obtain an I2O message. If there are none free then @@ -821,8 +833,8 @@ } else { - dprintk(("non sg for %p, %d\n", SCpnt->request_buffer, - SCpnt->request_bufflen)); + dprintk(KERN_INFO "non sg for %p, %d\n", SCpnt->request_buffer, + SCpnt->request_bufflen); i2o_raw_writel(len = SCpnt->request_bufflen, lenptr); if(len == 0) { @@ -861,7 +873,7 @@ } mb(); - dprintk(("Issued %ld\n", current_command->serial_number)); + dprintk(KERN_INFO "Issued %ld\n", current_command->serial_number); return 0; } diff -Nru a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c --- a/drivers/mtd/chips/cfi_cmdset_0020.c Sun Mar 7 18:39:37 2004 +++ b/drivers/mtd/chips/cfi_cmdset_0020.c Sun Mar 7 18:39:37 2004 @@ -1460,3 +1460,5 @@ module_init(cfi_staa_init); module_exit(cfi_staa_exit); + +MODULE_LICENSE("GPL"); diff -Nru a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c --- a/drivers/mtd/maps/map_funcs.c Sun Mar 7 18:39:36 2004 +++ b/drivers/mtd/maps/map_funcs.c Sun Mar 7 18:39:36 2004 @@ -93,3 +93,4 @@ } EXPORT_SYMBOL(simple_map_init); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/net/e100.c b/drivers/net/e100.c --- a/drivers/net/e100.c Sun Mar 7 18:39:38 2004 +++ b/drivers/net/e100.c Sun Mar 7 18:39:38 2004 @@ -158,7 +158,7 @@ #define DRV_NAME "e100" -#define DRV_VERSION "3.0.15" +#define DRV_VERSION "3.0.16" #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 1999-2004 Intel Corporation" #define PFX DRV_NAME ": " @@ -1032,8 +1032,9 @@ nic->phy = (u32)id_hi << 16 | (u32)id_lo; DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy); - /* Handle National tx phy */ - if(nic->phy == phy_nsc_tx) { + /* Handle National tx phys */ +#define NCS_PHY_MODEL_MASK 0xFFF0FFFF + if((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) { /* Disable congestion control */ cong = mdio_read(netdev, nic->mii.phy_id, MII_NSC_CONG); cong |= NSC_CONG_TXREADY; diff -Nru a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c --- a/drivers/net/irda/stir4200.c Sun Mar 7 18:39:37 2004 +++ b/drivers/net/irda/stir4200.c Sun Mar 7 18:39:37 2004 @@ -49,12 +49,14 @@ #include #include #include +#include #include #include #include #include #include -#include +#include +#include MODULE_AUTHOR("Stephen Hemminger "); MODULE_DESCRIPTION("IrDA-USB Dongle Driver for SigmaTel STIr4200"); @@ -72,15 +74,11 @@ module_param(tx_power, int, 0); MODULE_PARM_DESC(tx_power, "Set Transmitter power (0-3, 0 is highest power)"); -static int rx_interval = 5; /* milliseconds */ -module_param(rx_interval, int, 0); -MODULE_PARM_DESC(rx_interval, "Receive polling interval (ms)"); - #define STIR_IRDA_HEADER 4 #define CTRL_TIMEOUT 100 /* milliseconds */ #define TRANSMIT_TIMEOUT 200 /* milliseconds */ #define STIR_FIFO_SIZE 4096 -#define NUM_RX_URBS 2 +#define FIFO_REGS_SIZE 3 enum FirChars { FIR_CE = 0x7d, @@ -167,36 +165,26 @@ TEST_TSTOSC = 0x0F, }; -enum StirState { - STIR_STATE_RECEIVING=0, - STIR_STATE_TXREADY, -}; - struct stir_cb { struct usb_device *usbdev; /* init: probe_irda */ struct net_device *netdev; /* network layer */ struct irlap_cb *irlap; /* The link layer we are binded to */ struct net_device_stats stats; /* network statistics */ struct qos_info qos; - unsigned long state; unsigned speed; /* Current speed */ wait_queue_head_t thr_wait; /* transmit thread wakeup */ struct completion thr_exited; pid_t thr_pid; - unsigned int tx_bulkpipe; - void *tx_data; /* wrapped data out */ - unsigned tx_len; - unsigned tx_newspeed; - unsigned tx_mtt; + struct sk_buff *tx_pending; + void *io_buf; /* transmit/receive buffer */ + __u8 *fifo_status; - unsigned int rx_intpipe; iobuff_t rx_buff; /* receive unwrap state machine */ - struct timespec rx_time; - - struct urb *rx_urbs[NUM_RX_URBS]; - void *rx_data[NUM_RX_URBS]; + struct timeval rx_time; + int receiving; + struct urb *rx_urb; }; @@ -209,9 +197,6 @@ MODULE_DEVICE_TABLE(usb, dongles); -static int fifo_txwait(struct stir_cb *stir, unsigned space); -static void stir_usb_receive(struct urb *urb, struct pt_regs *regs); - /* Send control message to set dongle register */ static int write_reg(struct stir_cb *stir, __u16 reg, __u8 value) { @@ -239,6 +224,11 @@ MSECS_TO_JIFFIES(CTRL_TIMEOUT)); } +static inline int isfir(u32 speed) +{ + return (speed == 4000000); +} + /* * Prepare a FIR IrDA frame for transmission to the USB dongle. The * FIR transmit frame is documented in the datasheet. It consists of @@ -333,8 +323,8 @@ { iobuff_t *rx_buff = &stir->rx_buff; int len = rx_buff->len - 4; + struct sk_buff *skb, *nskb; __u32 fcs; - struct sk_buff *nskb; if (unlikely(len <= 0)) { pr_debug("%s: short frame len %d\n", @@ -345,41 +335,46 @@ return; } - fcs = rx_buff->data[len] | - rx_buff->data[len+1] << 8 | - rx_buff->data[len+2] << 16 | - rx_buff->data[len+3] << 24; - - if (unlikely(fcs != ~(crc32_le(~0, rx_buff->data, len)))) { - pr_debug("%s: crc error\n", stir->netdev->name); - irda_device_set_media_busy(stir->netdev, TRUE); + fcs = ~(crc32_le(~0, rx_buff->data, len)); + if (fcs != le32_to_cpu(get_unaligned((u32 *)(rx_buff->data+len)))) { + pr_debug("crc error calc 0x%x len %d\n", fcs, len); stir->stats.rx_errors++; stir->stats.rx_crc_errors++; return; } - /* If can't get new buffer, just drop and reuse */ - nskb = dev_alloc_skb(IRDA_SKB_MAX_MTU); - if (unlikely(!nskb)) - ++stir->stats.rx_dropped; - else { - struct sk_buff *oskb = rx_buff->skb; + /* if frame is short then just copy it */ + if (len < IRDA_RX_COPY_THRESHOLD) { + nskb = dev_alloc_skb(len + 1); + if (unlikely(!nskb)) { + ++stir->stats.rx_dropped; + return; + } + skb_reserve(nskb, 1); + skb = nskb; + memcpy(nskb->data, rx_buff->data, len); + } else { + nskb = dev_alloc_skb(rx_buff->truesize); + if (unlikely(!nskb)) { + ++stir->stats.rx_dropped; + return; + } skb_reserve(nskb, 1); + skb = rx_buff->skb; + rx_buff->skb = nskb; + rx_buff->head = nskb->data; + } - /* Set correct length in socket buffer */ - skb_put(oskb, len); + skb_put(skb, len); - oskb->mac.raw = oskb->data; - oskb->protocol = htons(ETH_P_IRDA); - oskb->dev = stir->netdev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + skb->dev = stir->netdev; - netif_rx(oskb); + netif_rx(skb); - stir->stats.rx_packets++; - stir->stats.rx_bytes += len; - rx_buff->skb = nskb; - rx_buff->head = nskb->data; - } + stir->stats.rx_packets++; + stir->stats.rx_bytes += len; rx_buff->data = rx_buff->head; rx_buff->len = 0; @@ -402,7 +397,6 @@ continue; /* Now receiving frame */ rx_buff->state = BEGIN_FRAME; - rx_buff->in_frame = TRUE; /* Time to initialize receive buffer */ rx_buff->data = rx_buff->head; @@ -424,6 +418,7 @@ if (byte == FIR_EOF) continue; rx_buff->state = INSIDE_FRAME; + rx_buff->in_frame = TRUE; /* fall through */ case INSIDE_FRAME: @@ -461,7 +456,6 @@ error_recovery: ++stir->stats.rx_errors; - irda_device_set_media_busy(stir->netdev, TRUE); rx_buff->state = OUTSIDE_FRAME; rx_buff->in_frame = FALSE; } @@ -478,11 +472,6 @@ &stir->rx_buff, bytes[i]); } -static inline int isfir(u32 speed) -{ - return (speed == 4000000); -} - static inline void unwrap_chars(struct stir_cb *stir, const __u8 *bytes, int length) { @@ -519,25 +508,31 @@ int i, err; __u8 mode; - pr_debug("%s: change speed %d\n", stir->netdev->name, speed); for (i = 0; i < ARRAY_SIZE(stir_modes); ++i) { if (speed == stir_modes[i].speed) goto found; } - ERROR("%s: invalid speed %d\n", stir->netdev->name, speed); + warn("%s: invalid speed %d", stir->netdev->name, speed); return -EINVAL; found: - pr_debug("%s: speed change from %d to %d\n", - stir->netdev->name, stir->speed, speed); + pr_debug("speed change from %d to %d\n", stir->speed, speed); + + /* sometimes needed to get chip out of stuck state */ + err = usb_reset_device(stir->usbdev); + if (err) + goto out; + + /* Reset modulator */ + err = write_reg(stir, REG_CTRL1, CTRL1_SRESET); + if (err) + goto out; - /* Make sure any previous Tx is really finished. This happens - * when we answer an incomming request ; the ua:rsp and the - * speed change are bundled together, so we need to wait until - * the packet we just submitted has been sent. Jean II */ - if (fifo_txwait(stir, 0)) - return -EIO; + /* Undocumented magic to tweak the DPLL */ + err = write_reg(stir, REG_DPLL, 0x15); + if (err) + goto out; /* Set clock */ err = write_reg(stir, REG_PDCLK, stir_modes[i].pdclk); @@ -564,33 +559,13 @@ goto out; err = write_reg(stir, REG_CTRL1, (tx_power & 3) << 1); - - out: - stir->speed = speed; - return err; -} - -static int stir_reset(struct stir_cb *stir) -{ - int err; - - /* reset state */ - stir->rx_buff.in_frame = FALSE; - stir->rx_buff.state = OUTSIDE_FRAME; - stir->speed = -1; - - /* Undocumented magic to tweak the DPLL */ - err = write_reg(stir, REG_DPLL, 0x15); if (err) goto out; /* Reset sensitivity */ err = write_reg(stir, REG_CTRL2, (rx_sensitivity & 7) << 5); - if (err) - goto out; - - err = change_speed(stir, 9600); out: + stir->speed = speed; return err; } @@ -606,48 +581,62 @@ /* the IRDA wrapping routines don't deal with non linear skb */ SKB_LINEAR_ASSERT(skb); - if (unlikely(skb->len) == 0) /* speed change only */ - stir->tx_len = 0; - else if (isfir(stir->speed)) - stir->tx_len = wrap_fir_skb(skb, stir->tx_data); - else - stir->tx_len = wrap_sir_skb(skb, stir->tx_data); - - stir->stats.tx_packets++; - stir->stats.tx_bytes += skb->len; - - stir->tx_mtt = irda_get_mtt(skb); - stir->tx_newspeed = irda_get_next_speed(skb); - - if (!test_and_set_bit(STIR_STATE_TXREADY, &stir->state)) - wake_up(&stir->thr_wait); + skb = xchg(&stir->tx_pending, skb); + wake_up(&stir->thr_wait); + + /* this should never happen unless stop/wakeup problem */ + if (unlikely(skb)) { + WARN_ON(1); + dev_kfree_skb(skb); + } - dev_kfree_skb(skb); return 0; } /* * Wait for the transmit FIFO to have space for next data + * + * If space < 0 then wait till FIFO completely drains. + * FYI: can take up to 13 seconds at 2400baud. */ -static int fifo_txwait(struct stir_cb *stir, unsigned space) +static int fifo_txwait(struct stir_cb *stir, int space) { int err; - unsigned count; - __u8 regs[3]; - unsigned long timeout = jiffies + HZ/10; + unsigned long count, status; + /* Read FIFO status and count */ for(;;) { - /* Read FIFO status and count */ - err = read_reg(stir, REG_FIFOCTL, regs, 3); - if (unlikely(err != 3)) { - WARNING("%s: FIFO register read error: %d\n", - stir->netdev->name, err); + err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, + FIFO_REGS_SIZE); + if (unlikely(err != FIFO_REGS_SIZE)) { + warn("%s: FIFO register read error: %d", + stir->netdev->name, err); + return err; } + status = stir->fifo_status[0]; + count = (unsigned)(stir->fifo_status[2] & 0x1f) << 8 + | stir->fifo_status[1]; + + pr_debug("fifo status 0x%lx count %lu\n", status, count); + + /* error when receive/transmit fifo gets confused */ + if (status & FIFOCTL_RXERR) { + stir->stats.rx_fifo_errors++; + stir->stats.rx_errors++; + break; + } + + if (status & FIFOCTL_TXERR) { + stir->stats.tx_fifo_errors++; + stir->stats.tx_errors++; + break; + } + /* is fifo receiving already, or empty */ - if (!(regs[0] & FIFOCTL_DIR) - || (regs[0] & FIFOCTL_EMPTY)) + if (!(status & FIFOCTL_DIR) + || (status & FIFOCTL_EMPTY)) return 0; if (signal_pending(current)) @@ -658,40 +647,37 @@ || !netif_device_present(stir->netdev)) return -ESHUTDOWN; - count = (unsigned)(regs[2] & 0x1f) << 8 | regs[1]; - - pr_debug("%s: fifo status 0x%x count %u\n", - stir->netdev->name, regs[0], count); - /* only waiting for some space */ - if (space && STIR_FIFO_SIZE - 4 > space + count) + if (space >= 0 && STIR_FIFO_SIZE - 4 > space + count) return 0; - if (time_after(jiffies, timeout)) { - WARNING("%s: transmit fifo timeout status=0x%x count=%d\n", - stir->netdev->name, regs[0], count); - ++stir->stats.tx_errors; - irda_device_set_media_busy(stir->netdev, TRUE); - return -ETIMEDOUT; - } - /* estimate transfer time for remaining chars */ wait_ms((count * 8000) / stir->speed); } + + err = write_reg(stir, REG_FIFOCTL, FIFOCTL_CLR); + if (err) + return err; + err = write_reg(stir, REG_FIFOCTL, 0); + if (err) + return err; + + return 0; } /* Wait for turnaround delay before starting transmit. */ -static void turnaround_delay(long us, const struct timespec *last) +static void turnaround_delay(const struct stir_cb *stir, long us) { long ticks; - struct timespec now = CURRENT_TIME; + struct timeval now; if (us <= 0) return; - us -= (now.tv_sec - last->tv_sec) * USEC_PER_SEC; - us -= (now.tv_nsec - last->tv_nsec) / NSEC_PER_USEC; + do_gettimeofday(&now); + us -= (now.tv_sec - stir->rx_time.tv_sec) * USEC_PER_SEC; + us -= now.tv_usec - stir->rx_time.tv_usec; if (us < 10) return; @@ -707,77 +693,60 @@ * Start receiver by submitting a request to the receive pipe. * If nothing is available it will return after rx_interval. */ -static void receive_start(struct stir_cb *stir) +static int receive_start(struct stir_cb *stir) { - int i; - - if (test_and_set_bit(STIR_STATE_RECEIVING, &stir->state)) - return; - - if (fifo_txwait(stir, 0)) - return; - - for (i = 0; i < NUM_RX_URBS; i++) { - struct urb *urb = stir->rx_urbs[i]; - - usb_fill_int_urb(urb, stir->usbdev, stir->rx_intpipe, - stir->rx_data[i], STIR_FIFO_SIZE, - stir_usb_receive, stir, rx_interval); - - if (usb_submit_urb(urb, GFP_KERNEL)) - urb->status = -EINVAL; - } + /* reset state */ + stir->receiving = 1; - if (i == 0) { - /* if nothing got queued, then just retry next time */ - if (net_ratelimit()) - WARNING("%s: no receive buffers avaiable\n", - stir->netdev->name); + stir->rx_buff.in_frame = FALSE; + stir->rx_buff.state = OUTSIDE_FRAME; - clear_bit(STIR_STATE_RECEIVING, &stir->state); - } + stir->rx_urb->status = 0; + return usb_submit_urb(stir->rx_urb, GFP_KERNEL); } /* Stop all pending receive Urb's */ static void receive_stop(struct stir_cb *stir) { - int i; + stir->receiving = 0; + usb_unlink_urb(stir->rx_urb); - for (i = 0; i < NUM_RX_URBS; i++) { - struct urb *urb = stir->rx_urbs[i]; - usb_unlink_urb(urb); - } + if (stir->rx_buff.in_frame) + stir->stats.collisions++; } - -/* Send wrapped data (in tx_data) to device */ -static void stir_send(struct stir_cb *stir) +/* + * Wrap data in socket buffer and send it. + */ +static void stir_send(struct stir_cb *stir, struct sk_buff *skb) { - int rc; + unsigned wraplen; + int first_frame = 0; - if (test_and_clear_bit(STIR_STATE_RECEIVING, &stir->state)) { + /* if receiving, need to turnaround */ + if (stir->receiving) { receive_stop(stir); - - turnaround_delay(stir->tx_mtt, &stir->rx_time); - - if (stir->rx_buff.in_frame) - ++stir->stats.collisions; + turnaround_delay(stir, irda_get_mtt(skb)); + first_frame = 1; } - else if (fifo_txwait(stir, stir->tx_len)) - return; /* shutdown or major errors */ + if (isfir(stir->speed)) + wraplen = wrap_fir_skb(skb, stir->io_buf); + else + wraplen = wrap_sir_skb(skb, stir->io_buf); + + /* check for space available in fifo */ + if (!first_frame) + fifo_txwait(stir, wraplen); + + stir->stats.tx_packets++; + stir->stats.tx_bytes += skb->len; stir->netdev->trans_start = jiffies; + pr_debug("send %d (%d)\n", skb->len, wraplen); - pr_debug("%s: send %d\n", stir->netdev->name, stir->tx_len); - rc = usb_bulk_msg(stir->usbdev, - stir->tx_bulkpipe, - stir->tx_data, stir->tx_len, - NULL, MSECS_TO_JIFFIES(TRANSMIT_TIMEOUT)); - - if (unlikely(rc)) { - WARNING("%s: usb bulk message failed %d\n", - stir->netdev->name, rc); + if (usb_bulk_msg(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1), + stir->io_buf, wraplen, + NULL, MSECS_TO_JIFFIES(TRANSMIT_TIMEOUT))) stir->stats.tx_errors++; - } } /* @@ -787,7 +756,7 @@ { struct stir_cb *stir = arg; struct net_device *dev = stir->netdev; - DECLARE_WAITQUEUE(wait, current); + struct sk_buff *skb; daemonize("%s", dev->name); allow_signal(SIGTERM); @@ -796,44 +765,58 @@ && netif_device_present(dev) && !signal_pending(current)) { - /* make swsusp happy with our thread */ + /* if suspending, then power off and wait */ if (current->flags & PF_FREEZE) { - receive_stop(stir); + if (stir->receiving) + receive_stop(stir); + else + fifo_txwait(stir, -1); write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD); refrigerator(PF_IOTHREAD); - stir_reset(stir); + if (change_speed(stir, stir->speed)) + break; } /* if something to send? */ - if (test_and_clear_bit(STIR_STATE_TXREADY, &stir->state)) { - unsigned new_speed = stir->tx_newspeed; - - /* Note that we may both send a packet and - * change speed in some cases. Jean II */ - - if (stir->tx_len != 0) - stir_send(stir); - - if (stir->speed != new_speed) - change_speed(stir, new_speed); - - netif_wake_queue(stir->netdev); + skb = xchg(&stir->tx_pending, NULL); + if (skb) { + unsigned new_speed = irda_get_next_speed(skb); + netif_wake_queue(dev); + + if (skb->len > 0) + stir_send(stir, skb); + dev_kfree_skb(skb); + + if (stir->speed != new_speed) { + if (fifo_txwait(stir, -1) || + change_speed(stir, new_speed)) + break; + } continue; } - if (irda_device_txqueue_empty(dev)) - receive_start(stir); + /* nothing to send? start receiving */ + if (!stir->receiving + && irda_device_txqueue_empty(dev)) { + /* Wait otherwise chip gets confused. */ + if (fifo_txwait(stir, -1)) + break; + + if (unlikely(receive_start(stir))) { + if (net_ratelimit()) + info("%s: receive usb submit failed", + stir->netdev->name); + stir->receiving = 0; + wait_ms(10); + continue; + } + } - set_task_state(current, TASK_INTERRUPTIBLE); - add_wait_queue(&stir->thr_wait, &wait); - if (test_bit(STIR_STATE_TXREADY, &stir->state)) - __set_task_state(current, TASK_RUNNING); - else - schedule_timeout(HZ/10); - remove_wait_queue(&stir->thr_wait, &wait); + /* sleep if nothing to send */ + wait_event_interruptible(stir->thr_wait, stir->tx_pending); } complete_and_exit (&stir->thr_exited, 0); @@ -841,48 +824,34 @@ /* - * Receive wrapped data into rx_data buffer. - * This chip doesn't block until data is available, we just have - * to read the FIFO perodically (ugh). + * USB bulk receive completion callback. + * Wakes up every ms (usb round trip) with wrapped + * data. */ -static void stir_usb_receive(struct urb *urb, struct pt_regs *regs) +static void stir_rcv_irq(struct urb *urb, struct pt_regs *regs) { struct stir_cb *stir = urb->context; int err; + /* in process of stopping, just drop data */ if (!netif_running(stir->netdev)) return; - switch (urb->status) { - case 0: - if(urb->actual_length > 0) { - pr_debug("%s: receive %d\n", - stir->netdev->name, urb->actual_length); - unwrap_chars(stir, urb->transfer_buffer, - urb->actual_length); - - stir->netdev->last_rx = jiffies; - stir->rx_time = CURRENT_TIME; - } - break; - - case -ECONNRESET: /* killed but pending */ - case -ENOENT: /* killed but not in use */ - case -ESHUTDOWN: - /* These are normal errors when URB is cancelled */ - stir->rx_buff.in_frame = FALSE; - stir->rx_buff.state = OUTSIDE_FRAME; + /* unlink, shutdown, unplug, other nasties */ + if (urb->status != 0) return; - default: - WARNING("%s: received status %d\n", stir->netdev->name, - urb->status); - stir->stats.rx_errors++; - urb->status = 0; + if (urb->actual_length > 0) { + pr_debug("receive %d\n", urb->actual_length); + unwrap_chars(stir, urb->transfer_buffer, + urb->actual_length); + + stir->netdev->last_rx = jiffies; + do_gettimeofday(&stir->rx_time); } /* kernel thread is stopping receiver don't resubmit */ - if (!test_bit(STIR_STATE_RECEIVING, &stir->state)) + if (!stir->receiving) return; /* resubmit existing urb */ @@ -890,14 +859,13 @@ /* in case of error, the kernel thread will restart us */ if (err) { - WARNING("%s: usb receive submit error: %d\n", + warn("%s: usb receive submit error: %d", stir->netdev->name, err); - urb->status = -ENOENT; + stir->receiving = 0; wake_up(&stir->thr_wait); } } - /* * Function stir_net_open (dev) * @@ -906,50 +874,50 @@ static int stir_net_open(struct net_device *netdev) { struct stir_cb *stir = netdev->priv; - int i, err; - char hwname[16]; + int err; + char hwname[16]; - err = stir_reset(stir); + err = usb_clear_halt(stir->usbdev, usb_sndbulkpipe(stir->usbdev, 1)); + if (err) + goto err_out1; + err = usb_clear_halt(stir->usbdev, usb_rcvbulkpipe(stir->usbdev, 2)); if (err) goto err_out1; - err = -ENOMEM; - - /* Note: Max SIR frame possible is 4273 */ - stir->tx_data = kmalloc(STIR_FIFO_SIZE, GFP_KERNEL); - if (!stir->tx_data) { - ERROR("%s(), alloc failed for rxbuf!\n", __FUNCTION__); + err = change_speed(stir, 9600); + if (err) goto err_out1; - } + + err = -ENOMEM; /* Initialize for SIR/FIR to copy data directly into skb. */ + stir->receiving = 0; stir->rx_buff.truesize = IRDA_SKB_MAX_MTU; stir->rx_buff.skb = dev_alloc_skb(IRDA_SKB_MAX_MTU); - if (!stir->rx_buff.skb) { - ERROR("%s(), dev_alloc_skb() failed for rxbuf!\n", - __FUNCTION__); - goto err_out2; - } + if (!stir->rx_buff.skb) + goto err_out1; + skb_reserve(stir->rx_buff.skb, 1); stir->rx_buff.head = stir->rx_buff.skb->data; - stir->rx_time = CURRENT_TIME; + do_gettimeofday(&stir->rx_time); - /* Allocate N receive buffer's and urbs */ - for (i = 0; i < NUM_RX_URBS; i++) { - stir->rx_urbs[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!stir->rx_urbs[i]){ - ERROR("%s(), usb_alloc_urb failed\n", __FUNCTION__); - goto err_out3; - } + stir->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!stir->rx_urb) + goto err_out2; - stir->rx_data[i] = kmalloc(STIR_FIFO_SIZE, GFP_KERNEL); - if (!stir->rx_data) { - usb_free_urb(stir->rx_urbs[i]); - ERROR("%s(), alloc failed for rxbuf!\n", __FUNCTION__); - goto err_out3; - } - } + stir->io_buf = kmalloc(STIR_FIFO_SIZE, GFP_KERNEL); + if (!stir->io_buf) + goto err_out3; + usb_fill_bulk_urb(stir->rx_urb, stir->usbdev, + usb_rcvbulkpipe(stir->usbdev, 2), + stir->io_buf, STIR_FIFO_SIZE, + stir_rcv_irq, stir); + + stir->fifo_status = kmalloc(FIFO_REGS_SIZE, GFP_KERNEL); + if (!stir->fifo_status) + goto err_out4; + /* * Now that everything should be initialized properly, * Open new IrLAP layer instance to take care of us... @@ -958,8 +926,8 @@ sprintf(hwname, "usb#%d", stir->usbdev->devnum); stir->irlap = irlap_open(netdev, &stir->qos, hwname); if (!stir->irlap) { - ERROR("%s(): irlap_open failed\n", __FUNCTION__); - goto err_out3; + err("irlap_open failed"); + goto err_out5; } /** Start kernel thread for transmit. */ @@ -967,25 +935,24 @@ CLONE_FS|CLONE_FILES); if (stir->thr_pid < 0) { err = stir->thr_pid; - WARNING("%s: unable to start kernel thread\n", - stir->netdev->name); - goto err_out4; + err("unable to start kernel thread"); + goto err_out6; } netif_start_queue(netdev); return 0; - err_out4: + err_out6: irlap_close(stir->irlap); + err_out5: + kfree(stir->fifo_status); + err_out4: + kfree(stir->io_buf); err_out3: - while(--i >= 0) { - usb_free_urb(stir->rx_urbs[i]); - kfree(stir->rx_data[i]); - } - kfree_skb(stir->rx_buff.skb); + usb_free_urb(stir->rx_urb); err_out2: - kfree(stir->tx_data); + kfree_skb(stir->rx_buff.skb); err_out1: return err; } @@ -999,7 +966,6 @@ static int stir_net_close(struct net_device *netdev) { struct stir_cb *stir = netdev->priv; - int i; /* Stop transmit processing */ netif_stop_queue(netdev); @@ -1007,15 +973,13 @@ /* Kill transmit thread */ kill_proc(stir->thr_pid, SIGTERM, 1); wait_for_completion(&stir->thr_exited); - kfree(stir->tx_data); - - clear_bit(STIR_STATE_RECEIVING, &stir->state); - receive_stop(stir); + kfree(stir->fifo_status); - for (i = 0; i < NUM_RX_URBS; i++) { - usb_free_urb(stir->rx_urbs[i]); - kfree(stir->rx_data[i]); - } + /* Mop up receive urb's */ + usb_unlink_urb(stir->rx_urb); + + kfree(stir->io_buf); + usb_free_urb(stir->rx_urb); kfree_skb(stir->rx_buff.skb); /* Stop and remove instance of IrLAP */ @@ -1057,7 +1021,7 @@ case SIOCGRECEIVING: /* Only approximately true */ - irq->ifr_receiving = test_bit(STIR_STATE_RECEIVING, &stir->state); + irq->ifr_receiving = stir->receiving; break; default: @@ -1077,53 +1041,6 @@ } /* - * Parse the various endpoints and find the one we need. - * - * The endpoint are the pipes used to communicate with the USB device. - * The spec defines 2 endpoints of type bulk transfer, one in, and one out. - * These are used to pass frames back and forth with the dongle. - */ -static int stir_setup_usb(struct stir_cb *stir, struct usb_interface *intf) -{ - struct usb_device *usbdev = interface_to_usbdev(intf); - const struct usb_host_interface *interface - = &intf->altsetting[intf->act_altsetting]; - const struct usb_endpoint_descriptor *ep_in = NULL; - const struct usb_endpoint_descriptor *ep_out = NULL; - int i; - - if (interface->desc.bNumEndpoints != 2) { - WARNING("%s: expected two endpoints\n", __FUNCTION__); - return -ENODEV; - } - - for(i = 0; i < interface->desc.bNumEndpoints; i++) { - const struct usb_endpoint_descriptor *ep - = &interface->endpoint[i].desc; - - if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK) { - /* We need to find an IN and an OUT */ - if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) - ep_in = ep; - else - ep_out = ep; - } else - WARNING("%s: unknown endpoint type 0x%x\n", - __FUNCTION__, ep->bmAttributes); - } - - if (!ep_in || !ep_out) - return -EIO; - - stir->tx_bulkpipe = usb_sndbulkpipe(usbdev, - ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - stir->rx_intpipe = usb_rcvintpipe(usbdev, - ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - return 0; -} - -/* * This routine is called by the USB subsystem for each new device * in the system. We need to check if the device is ours, and in * this case start handling it. @@ -1149,9 +1066,9 @@ stir->netdev = net; stir->usbdev = dev; - ret = stir_setup_usb(stir, intf); + ret = usb_reset_configuration(dev); if (ret != 0) { - ERROR("%s(), Bogus endpoints...\n", __FUNCTION__); + err("usb reset configuration failed"); goto err_out2; } @@ -1180,10 +1097,6 @@ net->get_stats = stir_net_get_stats; net->do_ioctl = stir_net_ioctl; - ret = stir_reset(stir); - if (ret) - goto err_out2; - ret = register_netdev(net); if (ret != 0) goto err_out2; @@ -1206,23 +1119,14 @@ static void stir_disconnect(struct usb_interface *intf) { struct stir_cb *stir = usb_get_intfdata(intf); - struct net_device *net; - usb_set_intfdata(intf, NULL); if (!stir) return; - /* Stop transmitter */ - net = stir->netdev; - netif_device_detach(net); - - /* Remove netdevice */ - unregister_netdev(net); - - /* No longer attached to USB bus */ - stir->usbdev = NULL; + unregister_netdev(stir->netdev); + free_netdev(stir->netdev); - free_netdev(net); + usb_set_intfdata(intf, NULL); } diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c --- a/drivers/net/ns83820.c Sun Mar 7 18:39:38 2004 +++ b/drivers/net/ns83820.c Sun Mar 7 18:39:38 2004 @@ -598,7 +598,7 @@ } static void FASTCALL(rx_refill_atomic(struct net_device *ndev)); -static void rx_refill_atomic(struct net_device *ndev) +static void fastcall rx_refill_atomic(struct net_device *ndev) { rx_refill(ndev, GFP_ATOMIC); } @@ -620,7 +620,7 @@ } static void FASTCALL(phy_intr(struct net_device *ndev)); -static void phy_intr(struct net_device *ndev) +static void fastcall phy_intr(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" }; @@ -807,7 +807,7 @@ } static void FASTCALL(ns83820_rx_kick(struct net_device *ndev)); -static void ns83820_rx_kick(struct net_device *ndev) +static void fastcall ns83820_rx_kick(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); /*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ { @@ -829,7 +829,7 @@ * */ static void FASTCALL(rx_irq(struct net_device *ndev)); -static void rx_irq(struct net_device *ndev) +static void fastcall rx_irq(struct net_device *ndev) { struct ns83820 *dev = PRIV(ndev); struct rx_info *info = &dev->rx_info; diff -Nru a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c --- a/drivers/net/tulip/interrupt.c Sun Mar 7 18:39:37 2004 +++ b/drivers/net/tulip/interrupt.c Sun Mar 7 18:39:37 2004 @@ -211,7 +211,7 @@ if (tp->rx_buffers[entry].mapping != le32_to_cpu(tp->rx_ring[entry].buffer1)) { printk(KERN_ERR "%s: Internal fault: The skbuff addresses " - "do not match in tulip_rx: %08x vs. %llx %p / %p.\n", + "do not match in tulip_rx: %08x vs. %08llx %p / %p.\n", dev->name, le32_to_cpu(tp->rx_ring[entry].buffer1), (unsigned long long)tp->rx_buffers[entry].mapping, diff -Nru a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c --- a/drivers/net/wan/wanxl.c Sun Mar 7 18:39:38 2004 +++ b/drivers/net/wan/wanxl.c Sun Mar 7 18:39:38 2004 @@ -31,7 +31,7 @@ #include "wanxl.h" -static const char* version = "wanXL serial card driver version: 0.47"; +static const char* version = "wanXL serial card driver version: 0.48"; #define PLX_CTL_RESET 0x40000000 /* adapter reset */ @@ -73,12 +73,11 @@ u8 *plx; /* PLX PCI9060 virtual base address */ struct pci_dev *pdev; /* for pdev->slot_name */ - port_t *ports[4]; int rx_in; struct sk_buff *rx_skbs[RX_QUEUE_LENGTH]; card_status_t *status; /* shared between host and card */ dma_addr_t status_address; - port_t __ports[0]; + port_t ports[0]; /* 1 - 4 port_t structures follow */ }card_t; @@ -89,18 +88,6 @@ } -static inline struct net_device *port_to_dev(port_t* port) -{ - return port->dev; -} - - -static inline const char* port_name(port_t *port) -{ - return port_to_dev(port)->name; -} - - static inline const char* card_name(struct pci_dev *pdev) { return pdev->slot_name; @@ -165,9 +152,9 @@ dte = (value & STATUS_CABLE_DCE) ? " DCE" : " DTE"; } printk(KERN_INFO "%s: %s%s module, %s cable%s%s\n", - port_name(port), pm, dte, cable, dsr, dcd); + port->dev->name, pm, dte, cable, dsr, dcd); - hdlc_set_carrier(value & STATUS_CABLE_DCD, port_to_dev(port)); + hdlc_set_carrier(value & STATUS_CABLE_DCD, port->dev); } @@ -175,7 +162,7 @@ /* Transmit complete interrupt service */ static inline void wanxl_tx_intr(port_t *port) { - struct net_device *dev = port_to_dev(port); + struct net_device *dev = port->dev; struct net_device_stats *stats = hdlc_stats(dev); while (1) { desc_t *desc = &get_status(port)->tx_descs[port->tx_in]; @@ -210,47 +197,49 @@ static inline void wanxl_rx_intr(card_t *card) { desc_t *desc; - while(desc = &card->status->rx_descs[card->rx_in], - desc->stat != PACKET_EMPTY) { - struct sk_buff *skb = card->rx_skbs[card->rx_in]; - port_t *port = card->ports[desc->stat & PACKET_PORT_MASK]; - struct net_device *dev = port_to_dev(port); - struct net_device_stats *stats = hdlc_stats(dev); - + while (desc = &card->status->rx_descs[card->rx_in], + desc->stat != PACKET_EMPTY) { if ((desc->stat & PACKET_PORT_MASK) > card->n_ports) printk(KERN_CRIT "wanXL %s: received packet for" " nonexistent port\n", card_name(card->pdev)); - - else if (!skb) - stats->rx_dropped++; - else { - pci_unmap_single(card->pdev, desc->address, - BUFFER_LENGTH, PCI_DMA_FROMDEVICE); - skb_put(skb, desc->length); + struct sk_buff *skb = card->rx_skbs[card->rx_in]; + port_t *port = &card->ports[desc->stat & + PACKET_PORT_MASK]; + struct net_device *dev = port->dev; + struct net_device_stats *stats = hdlc_stats(dev); + + if (!skb) + stats->rx_dropped++; + else { + pci_unmap_single(card->pdev, desc->address, + BUFFER_LENGTH, + PCI_DMA_FROMDEVICE); + skb_put(skb, desc->length); #ifdef DEBUG_PKT - printk(KERN_DEBUG "%s RX(%i):", port_name(port), - skb->len); - debug_frame(skb); + printk(KERN_DEBUG "%s RX(%i):", dev->name, + skb->len); + debug_frame(skb); #endif - stats->rx_packets++; - stats->rx_bytes += skb->len; - skb->mac.raw = skb->data; - skb->dev = dev; - dev->last_rx = jiffies; - skb->protocol = hdlc_type_trans(skb, dev); - netif_rx(skb); - skb = NULL; - } - - if (!skb) { - skb = dev_alloc_skb(BUFFER_LENGTH); - desc->address = skb ? - pci_map_single(card->pdev, skb->data, - BUFFER_LENGTH, - PCI_DMA_FROMDEVICE) : 0; - card->rx_skbs[card->rx_in] = skb; + stats->rx_packets++; + stats->rx_bytes += skb->len; + skb->mac.raw = skb->data; + skb->dev = dev; + dev->last_rx = jiffies; + skb->protocol = hdlc_type_trans(skb, dev); + netif_rx(skb); + skb = NULL; + } + + if (!skb) { + skb = dev_alloc_skb(BUFFER_LENGTH); + desc->address = skb ? + pci_map_single(card->pdev, skb->data, + BUFFER_LENGTH, + PCI_DMA_FROMDEVICE) : 0; + card->rx_skbs[card->rx_in] = skb; + } } desc->stat = PACKET_EMPTY; /* Free descriptor */ card->rx_in = (card->rx_in + 1) % RX_QUEUE_LENGTH; @@ -273,9 +262,9 @@ for (i = 0; i < card->n_ports; i++) { if (stat & (1 << (DOORBELL_FROM_CARD_TX_0 + i))) - wanxl_tx_intr(card->ports[i]); + wanxl_tx_intr(&card->ports[i]); if (stat & (1 << (DOORBELL_FROM_CARD_CABLE_0 + i))) - wanxl_cable_intr(card->ports[i]); + wanxl_cable_intr(&card->ports[i]); } if (stat & (1 << DOORBELL_FROM_CARD_RX)) wanxl_rx_intr(card); @@ -297,8 +286,7 @@ if (desc->stat != PACKET_EMPTY) { /* should never happen - previous xmit should stop queue */ #ifdef DEBUG_PKT - printk(KERN_DEBUG "%s: transmitter buffer full\n", - port_name(port)); + printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); #endif netif_stop_queue(dev); spin_unlock_irq(&port->lock); @@ -306,7 +294,7 @@ } #ifdef DEBUG_PKT - printk(KERN_DEBUG "%s TX(%i):", port_name(port), skb->len); + printk(KERN_DEBUG "%s TX(%i):", dev->name, skb->len); debug_frame(skb); #endif @@ -324,8 +312,7 @@ if (get_status(port)->tx_descs[port->tx_out].stat != PACKET_EMPTY) { netif_stop_queue(dev); #ifdef DEBUG_PKT - printk(KERN_DEBUG "%s: transmitter buffer full\n", - port_name(port)); + printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); #endif } @@ -417,7 +404,7 @@ int i; if (get_status(port)->open) { - printk(KERN_ERR "%s: port already open\n", port_name(port)); + printk(KERN_ERR "%s: port already open\n", dev->name); return -EIO; } if ((i = hdlc_open(dev)) != 0) @@ -435,7 +422,7 @@ return 0; while (time_after(timeout, jiffies)); - printk(KERN_ERR "%s: unable to open port\n", port_name(port)); + printk(KERN_ERR "%s: unable to open port\n", dev->name); /* ask the card to close the port, should it be still alive */ writel(1 << (DOORBELL_TO_CARD_CLOSE_0 + port->node), dbr); return -EFAULT; @@ -461,7 +448,7 @@ while (time_after(timeout, jiffies)); if (get_status(port)->open) - printk(KERN_ERR "%s: unable to close port\n", port_name(port)); + printk(KERN_ERR "%s: unable to close port\n", dev->name); for (i = 0; i < TX_BUFFERS; i++) { desc_t *desc = &get_status(port)->tx_descs[i]; @@ -528,11 +515,10 @@ card_t *card = pci_get_drvdata(pdev); int i; - for (i = 0; i < 4; i++) - if (card->ports[i]) { - struct net_device *dev = port_to_dev(card->ports[i]); - unregister_hdlc_device(dev); - } + for (i = 0; i < card->n_ports; i++) { + unregister_hdlc_device(card->ports[i].dev); + free_netdev(card->ports[i].dev); + } /* unregister and free all host resources */ if (card->irq) @@ -555,13 +541,10 @@ pci_free_consistent(pdev, sizeof(card_status_t), card->status, card->status_address); - for (i = 0; i < card->n_ports; i++) - if (card->__ports[i].dev) - free_netdev(card->__ports[i].dev); - + pci_release_regions(pdev); + pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); kfree(card); - pci_release_regions(pdev); } @@ -599,13 +582,15 @@ work on most platforms */ if (pci_set_consistent_dma_mask(pdev, 0x0FFFFFFF) || pci_set_dma_mask(pdev, 0x0FFFFFFF)) { - printk(KERN_ERR "No usable DMA configuration\n"); + printk(KERN_ERR "wanXL: No usable DMA configuration\n"); return -EIO; } i = pci_request_regions(pdev, "wanXL"); - if (i) + if (i) { + pci_disable_device(pdev); return i; + } switch (pdev->device) { case PCI_DEVICE_ID_SBE_WANXL100: ports = 1; break; @@ -619,23 +604,13 @@ printk(KERN_ERR "wanXL %s: unable to allocate memory\n", card_name(pdev)); pci_release_regions(pdev); + pci_disable_device(pdev); return -ENOBUFS; } memset(card, 0, alloc_size); pci_set_drvdata(pdev, card); card->pdev = pdev; - card->n_ports = ports; - - for (i = 0; i < ports; i++) { - card->__ports[i].dev = alloc_hdlcdev(&card->__ports[i]); - if (!card->__ports[i].dev) { - printk(KERN_ERR "wanXL %s: unable to allocate memory\n", - card_name(pdev)); - wanxl_pci_remove_one(pdev); - return -ENOMEM; - } - } card->status = pci_alloc_consistent(pdev, sizeof(card_status_t), &card->status_address); @@ -655,7 +630,7 @@ to indicate the card can do 32-bit DMA addressing */ if (pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF) || pci_set_dma_mask(pdev, 0xFFFFFFFF)) { - printk(KERN_ERR "No usable DMA configuration\n"); + printk(KERN_ERR "wanXL: No usable DMA configuration\n"); wanxl_pci_remove_one(pdev); return -EIO; } @@ -767,17 +742,11 @@ ramsize = stat; #endif - printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq" - " %u\n" KERN_INFO "wanXL %s: port", card_name(pdev), - plx_phy, ramsize / 1024, mem_phy, pdev->irq, card_name(pdev)); - - for (i = 0; i < ports; i++) - printk("%s #%i: %s", i ? "," : "", i, - port_name(card->ports[i])); - printk("\n"); + printk(KERN_INFO "wanXL %s: at 0x%X, %u KB of RAM at 0x%X, irq %u\n", + card_name(pdev), plx_phy, ramsize / 1024, mem_phy, pdev->irq); /* Allocate IRQ */ - if(request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) { + if (request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) { printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n", card_name(pdev), pdev->irq); wanxl_pci_remove_one(pdev); @@ -786,9 +755,18 @@ card->irq = pdev->irq; for (i = 0; i < ports; i++) { - port_t *port = &card->__ports[i]; - struct net_device *dev = port_to_dev(port); - hdlc_device *hdlc = dev_to_hdlc(dev); + hdlc_device *hdlc; + port_t *port = &card->ports[i]; + struct net_device *dev = alloc_hdlcdev(port); + if (!dev) { + printk(KERN_ERR "wanXL %s: unable to allocate" + " memory\n", card_name(pdev)); + wanxl_pci_remove_one(pdev); + return -ENOMEM; + } + + port->dev = dev; + hdlc = dev_to_hdlc(dev); spin_lock_init(&port->lock); SET_MODULE_OWNER(dev); dev->tx_queue_len = 50; @@ -797,7 +775,6 @@ dev->stop = wanxl_close; hdlc->attach = wanxl_attach; hdlc->xmit = wanxl_xmit; - card->ports[i] = port; dev->get_stats = wanxl_get_stats; port->card = card; port->node = i; @@ -805,11 +782,21 @@ if (register_hdlc_device(dev)) { printk(KERN_ERR "wanXL %s: unable to register hdlc" " device\n", card_name(pdev)); - card->ports[i] = NULL; + free_netdev(dev); wanxl_pci_remove_one(pdev); return -ENOBUFS; } + card->n_ports++; } + + printk(KERN_INFO "wanXL %s: port", card_name(pdev)); + for (i = 0; i < ports; i++) + printk("%s #%i: %s", i ? "," : "", i, + card->ports[i].dev->name); + printk("\n"); + + for (i = 0; i < ports; i++) + wanxl_cable_intr(&card->ports[i]); /* get carrier status etc.*/ return 0; } diff -Nru a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c --- a/drivers/parport/parport_sunbpp.c Sun Mar 7 18:39:36 2004 +++ b/drivers/parport/parport_sunbpp.c Sun Mar 7 18:39:36 2004 @@ -44,9 +44,10 @@ #define dprintk(x) #endif -static void parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { parport_generic_irq(irq, (struct parport *) dev_id, regs); + return IRQ_HANDLED; } static void parport_sunbpp_disable_irq(struct parport *p) @@ -384,7 +385,7 @@ static void __exit parport_sunbpp_exit(void) { - while (!list_empty(port_list)) { + while (!list_empty(&port_list)) { Node *node = list_entry(port_list.next, Node, list); struct parport *p = node->port; struct parport_operations *ops = p->ops; diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids --- a/drivers/pci/pci.ids Sun Mar 7 18:39:37 2004 +++ b/drivers/pci/pci.ids Sun Mar 7 18:39:37 2004 @@ -5601,6 +5601,8 @@ 14da National Aerospace Laboratories 14db AFAVLAB Technology Inc 2120 TK9902 + 2180 P028 + 2182 P030 14dc Amplicon Liveline Ltd 0000 PCI230 0001 PCI242 diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c --- a/drivers/sbus/char/vfc_dev.c Sun Mar 7 18:39:37 2004 +++ b/drivers/sbus/char/vfc_dev.c Sun Mar 7 18:39:37 2004 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c --- a/drivers/scsi/qlogicfc.c Sun Mar 7 18:39:37 2004 +++ b/drivers/scsi/qlogicfc.c Sun Mar 7 18:39:37 2004 @@ -411,7 +411,7 @@ if that mbox should be copied as input. For example 0x2 would mean only copy mbox1. */ -const u_char mbox_param[] = +static const u_char mbox_param[] = { 0x01, /* MBOX_NO_OP */ 0x1f, /* MBOX_LOAD_RAM */ diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c --- a/drivers/scsi/qlogicpti.c Sun Mar 7 18:39:37 2004 +++ b/drivers/scsi/qlogicpti.c Sun Mar 7 18:39:37 2004 @@ -54,7 +54,7 @@ #define PACKB(a, b) (((a)<<4)|(b)) -const u_char mbox_param[] = { +static const u_char mbox_param[] = { PACKB(1, 1), /* MBOX_NO_OP */ PACKB(5, 5), /* MBOX_LOAD_RAM */ PACKB(2, 0), /* MBOX_EXEC_FIRMWARE */ diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c --- a/drivers/serial/8250.c Sun Mar 7 18:39:36 2004 +++ b/drivers/serial/8250.c Sun Mar 7 18:39:36 2004 @@ -16,12 +16,8 @@ * * A note about mapbase / membase * - * mapbase is the physical address of the IO port. Currently, we don't - * support this very well, and it may well be dropped from this driver - * in future. As such, mapbase should be NULL. - * - * membase is an 'ioremapped' cookie. This is compatible with the old - * serial.c driver, and is currently the preferred form. + * mapbase is the physical address of the IO port. + * membase is an 'ioremapped' cookie. */ #include #include @@ -1976,6 +1972,8 @@ if (co->index >= UART_NR) co->index = 0; port = &serial8250_ports[co->index].port; + if (!port->ops) + return -ENODEV; /* * Temporary fix. @@ -2006,6 +2004,14 @@ return 0; } console_initcall(serial8250_console_init); + +static int __init serial8250_late_console_init(void) +{ + if (!(serial8250_console.flags & CON_ENABLED)) + register_console(&serial8250_console); + return 0; +} +late_initcall(serial8250_late_console_init); #define SERIAL8250_CONSOLE &serial8250_console #else diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c --- a/drivers/serial/8250_pci.c Sun Mar 7 18:39:37 2004 +++ b/drivers/serial/8250_pci.c Sun Mar 7 18:39:37 2004 @@ -145,8 +145,10 @@ bar = FL_GET_BASE(board->flags); if (idx < 4) bar += idx; - else + else { + bar = 4; offset += (idx - 4) * board->uart_offset; + } return setup_port(dev, req, bar, offset, board->reg_shift); } @@ -1772,7 +1774,7 @@ pbn_b0_4_115200 }, { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - pbn_b0_2_115200 }, + pbn_b0_bt_2_921600 }, /* * Digitan DS560-558, from jimd@esoft.com @@ -1889,6 +1891,9 @@ * AFAVLAB serial card, from Harald Welte */ { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b0_bt_8_115200 }, + { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_8_115200 }, diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig Sun Mar 7 18:39:38 2004 +++ b/drivers/serial/Kconfig Sun Mar 7 18:39:38 2004 @@ -250,12 +250,6 @@ your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_CLPS711X_OLD_NAME - bool "Use the old 2.4 names for CLPS711X serial port" - depends on SERIAL_CLPS711X=y - help - ::: To be written ::: - config SERIAL_DZ bool "DECstation DZ serial driver" depends on DECSTATION diff -Nru a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c --- a/drivers/serial/clps711x.c Sun Mar 7 18:39:37 2004 +++ b/drivers/serial/clps711x.c Sun Mar 7 18:39:37 2004 @@ -49,18 +49,9 @@ #define UART_NR 2 -#ifndef CONFIG_SERIAL_CLPS711X_OLD_NAME #define SERIAL_CLPS711X_MAJOR 204 #define SERIAL_CLPS711X_MINOR 40 #define SERIAL_CLPS711X_NR UART_NR - -#else -#warning The old names/device number for this driver if compatabity is needed -#define SERIAL_CLPS711X_MAJOR 204 -#define SERIAL_CLPS711X_MINOR 16 -#define SERIAL_CLPS711X_NR UART_NR - -#endif /* * We use the relevant SYSCON register as a base address for these ports. diff -Nru a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c --- a/drivers/serial/serial_core.c Sun Mar 7 18:39:37 2004 +++ b/drivers/serial/serial_core.c Sun Mar 7 18:39:37 2004 @@ -175,8 +175,6 @@ uart_circ_clear(&info->xmit); } - port->mctrl = 0; - retval = port->ops->startup(port); if (retval == 0) { if (init_hw) { @@ -1873,9 +1871,6 @@ if (flow == 'r') termios.c_cflag |= CRTSCTS; - - if (!port->ops) - return 0; /* "console=" on ia64 */ port->ops->set_termios(port, &termios, NULL); co->cflag = termios.c_cflag; diff -Nru a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c --- a/drivers/usb/gadget/inode.c Sun Mar 7 18:39:37 2004 +++ b/drivers/usb/gadget/inode.c Sun Mar 7 18:39:37 2004 @@ -1812,7 +1812,6 @@ return -ENOMEM; inode->i_op = &simple_dir_inode_operations; if (!(d = d_alloc_root (inode))) { -enomem: iput (inode); return -ENOMEM; } @@ -1823,12 +1822,15 @@ */ dev = dev_new (); if (!dev) - goto enomem; + return -ENOMEM; + dev->sb = sb; if (!(inode = gadgetfs_create_file (sb, CHIP, dev, &dev_init_operations, - &dev->dentry))) - goto enomem; + &dev->dentry))) { + put_dev(dev); + return -ENOMEM; + } /* other endpoint files are available after hardware setup, * from binding to a controller. @@ -1849,8 +1851,10 @@ gadgetfs_kill_sb (struct super_block *sb) { kill_litter_super (sb); - put_dev (the_device); - the_device = 0; + if (the_device) { + put_dev (the_device); + the_device = 0; + } } /*----------------------------------------------------------------------*/ diff -Nru a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c --- a/drivers/usb/serial/safe_serial.c Sun Mar 7 18:39:36 2004 +++ b/drivers/usb/serial/safe_serial.c Sun Mar 7 18:39:37 2004 @@ -93,6 +93,7 @@ MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_LICENSE("GPL"); #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) #abort "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" diff -Nru a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c --- a/drivers/video/aty/radeon_base.c Sun Mar 7 18:39:37 2004 +++ b/drivers/video/aty/radeon_base.c Sun Mar 7 18:39:37 2004 @@ -135,7 +135,7 @@ CHIP_DEF(PCI_CHIP_R200_QM, R200, CHIP_HAS_CRTC2), /* Mobility M7 */ CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), - CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), + CHIP_DEF(PCI_CHIP_RADEON_LX, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), /* 7500 */ CHIP_DEF(PCI_CHIP_RV200_QW, RV200, CHIP_HAS_CRTC2), CHIP_DEF(PCI_CHIP_RV200_QX, RV200, CHIP_HAS_CRTC2), diff -Nru a/drivers/video/ffb.c b/drivers/video/ffb.c --- a/drivers/video/ffb.c Sun Mar 7 18:39:38 2004 +++ b/drivers/video/ffb.c Sun Mar 7 18:39:38 2004 @@ -466,6 +466,7 @@ static void ffb_switch_from_graph(struct ffb_par *par) { struct ffb_fbc *fbc = par->fbc; + struct ffb_dac *dac = par->dac; unsigned long flags; spin_lock_irqsave(&par->lock, flags); @@ -482,6 +483,14 @@ upa_writel(par->fg_cache, &fbc->fg); upa_writel(par->bg_cache, &fbc->bg); FFBWait(par); + + /* Disable cursor. */ + upa_writel(0x100, &dac->type2); + if (par->dac_rev <= 2) + upa_writel(0, &dac->value2); + else + upa_writel(3, &dac->value2); + spin_unlock_irqrestore(&par->lock, flags); } diff -Nru a/fs/adfs/super.c b/fs/adfs/super.c --- a/fs/adfs/super.c Sun Mar 7 18:39:36 2004 +++ b/fs/adfs/super.c Sun Mar 7 18:39:36 2004 @@ -333,6 +333,7 @@ struct object_info root_obj; unsigned char *b_data; struct adfs_sb_info *asb; + struct inode *root; asb = kmalloc(sizeof(*asb), GFP_KERNEL); if (!asb) @@ -443,10 +444,11 @@ asb->s_namelen = ADFS_F_NAME_LEN; } - sb->s_root = d_alloc_root(adfs_iget(sb, &root_obj)); + root = adfs_iget(sb, &root_obj); + sb->s_root = d_alloc_root(root); if (!sb->s_root) { int i; - + iput(root); for (i = 0; i < asb->s_map_size; i++) brelse(asb->s_map[i].dm_bh); kfree(asb->s_map); diff -Nru a/fs/afs/super.c b/fs/afs/super.c --- a/fs/afs/super.c Sun Mar 7 18:39:37 2004 +++ b/fs/afs/super.c Sun Mar 7 18:39:37 2004 @@ -280,7 +280,6 @@ return 0; error: - dput(root); iput(inode); afs_put_volume(as->volume); kfree(as); diff -Nru a/fs/aio.c b/fs/aio.c --- a/fs/aio.c Sun Mar 7 18:39:37 2004 +++ b/fs/aio.c Sun Mar 7 18:39:37 2004 @@ -312,7 +312,7 @@ /* wait_on_sync_kiocb: * Waits on the given sync kiocb to complete. */ -ssize_t wait_on_sync_kiocb(struct kiocb *iocb) +ssize_t fastcall wait_on_sync_kiocb(struct kiocb *iocb) { while (iocb->ki_users) { set_current_state(TASK_UNINTERRUPTIBLE); @@ -331,7 +331,7 @@ * go away, they will call put_ioctx and release any pinned memory * associated with the request (held via struct page * references). */ -void exit_aio(struct mm_struct *mm) +void fastcall exit_aio(struct mm_struct *mm) { struct kioctx *ctx = mm->ioctx_list; mm->ioctx_list = NULL; @@ -356,7 +356,7 @@ * Called when the last user of an aio context has gone away, * and the struct needs to be freed. */ -void __put_ioctx(struct kioctx *ctx) +void fastcall __put_ioctx(struct kioctx *ctx) { unsigned nr_events = ctx->max_reqs; @@ -383,7 +383,7 @@ * req (after submitting it) and aio_complete() freeing the req. */ static struct kiocb *FASTCALL(__aio_get_req(struct kioctx *ctx)); -static struct kiocb *__aio_get_req(struct kioctx *ctx) +static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx) { struct kiocb *req = NULL; struct aio_ring *ring; @@ -509,7 +509,7 @@ * Returns true if this put was the last user of the kiocb, * false if the request is still in use. */ -int aio_put_req(struct kiocb *req) +int fastcall aio_put_req(struct kiocb *req) { struct kioctx *ctx = req->ki_ctx; int ret; @@ -596,7 +596,7 @@ unuse_mm(ctx->mm); } -void kick_iocb(struct kiocb *iocb) +void fastcall kick_iocb(struct kiocb *iocb) { struct kioctx *ctx = iocb->ki_ctx; @@ -622,7 +622,7 @@ * Returns true if this is the last user of the request. The * only other user of the request can be the cancellation code. */ -int aio_complete(struct kiocb *iocb, long res, long res2) +int fastcall aio_complete(struct kiocb *iocb, long res, long res2) { struct kioctx *ctx = iocb->ki_ctx; struct aio_ring_info *info; @@ -985,7 +985,7 @@ return -EINVAL; } -int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, +int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, struct iocb *iocb) { struct kiocb *req; diff -Nru a/fs/autofs4/inode.c b/fs/autofs4/inode.c --- a/fs/autofs4/inode.c Sun Mar 7 18:39:37 2004 +++ b/fs/autofs4/inode.c Sun Mar 7 18:39:37 2004 @@ -213,6 +213,9 @@ * Get the root inode and dentry, but defer checking for errors. */ root_inode = autofs4_get_inode(s, autofs4_mkroot(sbi)); + if (!root_inode) + goto fail_free; + root_inode->i_op = &autofs4_root_inode_operations; root_inode->i_fop = &autofs4_root_operations; root = d_alloc_root(root_inode); @@ -264,22 +267,13 @@ */ fail_fput: printk("autofs: pipe file descriptor does not contain proper ops\n"); - /* - * fput() can block, so we clear the super block first. - */ fput(pipe); /* fall through */ fail_dput: - /* - * dput() can block, so we clear the super block first. - */ dput(root); goto fail_free; fail_iput: printk("autofs: get root dentry failed\n"); - /* - * iput() can block, so we clear the super block first. - */ iput(root_inode); fail_free: kfree(sbi); diff -Nru a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c --- a/fs/befs/linuxvfs.c Sun Mar 7 18:39:37 2004 +++ b/fs/befs/linuxvfs.c Sun Mar 7 18:39:37 2004 @@ -789,6 +789,7 @@ struct buffer_head *bh; befs_sb_info *befs_sb; befs_super_block *disk_sb; + struct inode *root; const unsigned long sb_block = 0; const off_t x86_sb_off = 512; @@ -863,9 +864,10 @@ /* Set real blocksize of fs */ sb_set_blocksize(sb, (ulong) befs_sb->block_size); sb->s_op = (struct super_operations *) &befs_sops; - sb->s_root = - d_alloc_root(iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir)))); + root = iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); + sb->s_root = d_alloc_root(root); if (!sb->s_root) { + iput(root); befs_error(sb, "get root inode failed"); goto unaquire_priv_sbp; } diff -Nru a/fs/buffer.c b/fs/buffer.c --- a/fs/buffer.c Sun Mar 7 18:39:37 2004 +++ b/fs/buffer.c Sun Mar 7 18:39:37 2004 @@ -97,7 +97,7 @@ } EXPORT_SYMBOL(wake_up_buffer); -void unlock_buffer(struct buffer_head *bh) +void fastcall unlock_buffer(struct buffer_head *bh) { /* * unlock_buffer against a zero-count bh is a bug, if the page @@ -404,7 +404,7 @@ struct inode *bd_inode = bdev->bd_inode; struct address_space *bd_mapping = bd_inode->i_mapping; struct buffer_head *ret = NULL; - unsigned long index; + pgoff_t index; struct buffer_head *bh; struct buffer_head *head; struct page *page; @@ -1093,7 +1093,7 @@ */ static void init_page_buffers(struct page *page, struct block_device *bdev, - int block, int size) + sector_t block, int size) { struct buffer_head *head = page_buffers(page); struct buffer_head *bh = head; @@ -1121,8 +1121,8 @@ * This is user purely for blockdev mappings. */ static struct page * -grow_dev_page(struct block_device *bdev, unsigned long block, - unsigned long index, int size) +grow_dev_page(struct block_device *bdev, sector_t block, + pgoff_t index, int size) { struct inode *inode = bdev->bd_inode; struct page *page; @@ -1178,10 +1178,10 @@ * grow_dev_page() will go BUG() if this happens. */ static inline int -grow_buffers(struct block_device *bdev, unsigned long block, int size) +grow_buffers(struct block_device *bdev, sector_t block, int size) { struct page *page; - unsigned long index; + pgoff_t index; int sizebits; /* Size must be multiple of hard sectorsize */ @@ -1256,7 +1256,7 @@ * mark_buffer_dirty() is atomic. It takes bh->b_page->mapping->private_lock, * mapping->page_lock and the global inode_lock. */ -void mark_buffer_dirty(struct buffer_head *bh) +void fastcall mark_buffer_dirty(struct buffer_head *bh) { if (!buffer_uptodate(bh)) buffer_error(); @@ -1738,8 +1738,8 @@ get_block_t *get_block, struct writeback_control *wbc) { int err; - unsigned long block; - unsigned long last_block; + sector_t block; + sector_t last_block; struct buffer_head *bh, *head; int nr_underway = 0; @@ -2207,7 +2207,7 @@ struct address_space *mapping = page->mapping; struct inode *inode = mapping->host; struct page *new_page; - unsigned long pgpos; + pgoff_t pgpos; long status; unsigned zerofrom; unsigned blocksize = 1 << inode->i_blkbits; @@ -2317,6 +2317,28 @@ return 0; } + +/* + * nobh_prepare_write()'s prereads are special: the buffer_heads are freed + * immediately, while under the page lock. So it needs a special end_io + * handler which does not touch the bh after unlocking it. + * + * Note: unlock_buffer() sort-of does touch the bh after unlocking it, but + * a race there is benign: unlock_buffer() only use the bh's address for + * hashing after unlocking the buffer, so it doesn't actually touch the bh + * itself. + */ +static void end_buffer_read_nobh(struct buffer_head *bh, int uptodate) +{ + if (uptodate) { + set_buffer_uptodate(bh); + } else { + /* This happens, due to failed READA attempts. */ + clear_buffer_uptodate(bh); + } + unlock_buffer(bh); +} + /* * On entry, the page is fully not uptodate. * On exit the page is fully uptodate in the areas outside (from,to) @@ -2408,12 +2430,25 @@ } if (nr_reads) { - ll_rw_block(READ, nr_reads, read_bh); + struct buffer_head *bh; + + /* + * The page is locked, so these buffers are protected from + * any VM or truncate activity. Hence we don't need to care + * for the buffer_head refcounts. + */ + for (i = 0; i < nr_reads; i++) { + bh = read_bh[i]; + lock_buffer(bh); + bh->b_end_io = end_buffer_read_nobh; + submit_bh(READ, bh); + } for (i = 0; i < nr_reads; i++) { - wait_on_buffer(read_bh[i]); - if (!buffer_uptodate(read_bh[i])) + bh = read_bh[i]; + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) ret = -EIO; - free_buffer_head(read_bh[i]); + free_buffer_head(bh); read_bh[i] = NULL; } if (ret) @@ -2512,9 +2547,11 @@ int block_truncate_page(struct address_space *mapping, loff_t from, get_block_t *get_block) { - unsigned long index = from >> PAGE_CACHE_SHIFT; + pgoff_t index = from >> PAGE_CACHE_SHIFT; unsigned offset = from & (PAGE_CACHE_SIZE-1); - unsigned blocksize, iblock, length, pos; + unsigned blocksize; + pgoff_t iblock; + unsigned length, pos; struct inode *inode = mapping->host; struct page *page; struct buffer_head *bh; @@ -2594,7 +2631,7 @@ { struct inode * const inode = page->mapping->host; loff_t i_size = i_size_read(inode); - const unsigned long end_index = i_size >> PAGE_CACHE_SHIFT; + const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; unsigned offset; void *kaddr; diff -Nru a/fs/coda/inode.c b/fs/coda/inode.c --- a/fs/coda/inode.c Sun Mar 7 18:39:37 2004 +++ b/fs/coda/inode.c Sun Mar 7 18:39:37 2004 @@ -195,6 +195,8 @@ printk("coda_read_super: rootinode is %ld dev %s\n", root->i_ino, root->i_sb->s_id); sb->s_root = d_alloc_root(root); + if (!sb->s_root) + goto error; return 0; error: diff -Nru a/fs/cramfs/inode.c b/fs/cramfs/inode.c --- a/fs/cramfs/inode.c Sun Mar 7 18:39:36 2004 +++ b/fs/cramfs/inode.c Sun Mar 7 18:39:36 2004 @@ -199,6 +199,7 @@ struct cramfs_super super; unsigned long root_offset; struct cramfs_sb_info *sbi; + struct inode *root; sbi = kmalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); if (!sbi) @@ -263,7 +264,14 @@ /* Set it all up.. */ sb->s_op = &cramfs_ops; - sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root)); + root = get_cramfs_inode(sb, &super.root); + if (!root) + goto out; + sb->s_root = d_alloc_root(root); + if (!sb->s_root) { + iput(root); + goto out; + } return 0; out: kfree(sbi); diff -Nru a/fs/efs/super.c b/fs/efs/super.c --- a/fs/efs/super.c Sun Mar 7 18:39:38 2004 +++ b/fs/efs/super.c Sun Mar 7 18:39:38 2004 @@ -210,6 +210,7 @@ { struct efs_sb_info *sb; struct buffer_head *bh; + struct inode *root; sb = kmalloc(sizeof(struct efs_sb_info), GFP_KERNEL); if (!sb) @@ -266,10 +267,12 @@ s->s_flags |= MS_RDONLY; } s->s_op = &efs_superblock_operations; - s->s_root = d_alloc_root(iget(s, EFS_ROOTINODE)); + root = iget(s, EFS_ROOTINODE); + s->s_root = d_alloc_root(root); if (!(s->s_root)) { printk(KERN_ERR "EFS: get root inode failed\n"); + iput(root); goto out_no_fs; } diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c --- a/fs/ext2/ialloc.c Sun Mar 7 18:39:37 2004 +++ b/fs/ext2/ialloc.c Sun Mar 7 18:39:37 2004 @@ -431,8 +431,8 @@ * That failed: try linear search for a free inode, even if that group * has no free blocks. */ - group = parent_group + 1; - for (i = 2; i < ngroups; i++) { + group = parent_group; + for (i = 0; i < ngroups; i++) { if (++group >= ngroups) group = 0; desc = ext2_get_group_desc (sb, group, &bh); diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c --- a/fs/ext2/super.c Sun Mar 7 18:39:37 2004 +++ b/fs/ext2/super.c Sun Mar 7 18:39:37 2004 @@ -563,6 +563,7 @@ struct buffer_head * bh; struct ext2_sb_info * sbi; struct ext2_super_block * es; + struct inode *root; unsigned long block, sb_block = 1; unsigned long logic_sb_block = get_sb_block(&data); unsigned long offset = 0; @@ -815,15 +816,17 @@ */ sb->s_op = &ext2_sops; sb->s_export_op = &ext2_export_ops; - sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO)); - if (!sb->s_root || !S_ISDIR(sb->s_root->d_inode->i_mode) || - !sb->s_root->d_inode->i_blocks || !sb->s_root->d_inode->i_size) { - if (sb->s_root) { - dput(sb->s_root); - sb->s_root = NULL; - printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); - } else - printk(KERN_ERR "EXT2-fs: get root inode failed\n"); + root = iget(sb, EXT2_ROOT_INO); + sb->s_root = d_alloc_root(root); + if (!sb->s_root) { + iput(root); + printk(KERN_ERR "EXT2-fs: get root inode failed\n"); + goto failed_mount2; + } + if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { + dput(sb->s_root); + sb->s_root = NULL; + printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); goto failed_mount2; } if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c --- a/fs/ext3/ialloc.c Sun Mar 7 18:39:37 2004 +++ b/fs/ext3/ialloc.c Sun Mar 7 18:39:37 2004 @@ -398,8 +398,8 @@ * That failed: try linear search for a free inode, even if that group * has no free blocks. */ - group = parent_group + 1; - for (i = 2; i < ngroups; i++) { + group = parent_group; + for (i = 0; i < ngroups; i++) { if (++group >= ngroups) group = 0; desc = ext3_get_group_desc (sb, group, &bh); diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c --- a/fs/ext3/super.c Sun Mar 7 18:39:38 2004 +++ b/fs/ext3/super.c Sun Mar 7 18:39:38 2004 @@ -1040,6 +1040,7 @@ unsigned long offset = 0; unsigned long journal_inum = 0; unsigned long def_mount_opts; + struct inode *root; int blocksize; int hblock; int db_count; @@ -1354,16 +1355,17 @@ * so we can safely mount the rest of the filesystem now. */ - sb->s_root = d_alloc_root(iget(sb, EXT3_ROOT_INO)); - if (!sb->s_root || !S_ISDIR(sb->s_root->d_inode->i_mode) || - !sb->s_root->d_inode->i_blocks || !sb->s_root->d_inode->i_size) { - if (sb->s_root) { - dput(sb->s_root); - sb->s_root = NULL; - printk(KERN_ERR - "EXT3-fs: corrupt root inode, run e2fsck\n"); - } else - printk(KERN_ERR "EXT3-fs: get root inode failed\n"); + root = iget(sb, EXT3_ROOT_INO); + sb->s_root = d_alloc_root(root); + if (!sb->s_root) { + printk(KERN_ERR "EXT3-fs: get root inode failed\n"); + iput(root); + goto failed_mount3; + } + if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { + dput(sb->s_root); + sb->s_root = NULL; + printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n"); goto failed_mount3; } diff -Nru a/fs/fcntl.c b/fs/fcntl.c --- a/fs/fcntl.c Sun Mar 7 18:39:37 2004 +++ b/fs/fcntl.c Sun Mar 7 18:39:37 2004 @@ -19,7 +19,7 @@ #include #include -void set_close_on_exec(unsigned int fd, int flag) +void fastcall set_close_on_exec(unsigned int fd, int flag) { struct files_struct *files = current->files; spin_lock(&files->file_lock); diff -Nru a/fs/file_table.c b/fs/file_table.c --- a/fs/file_table.c Sun Mar 7 18:39:36 2004 +++ b/fs/file_table.c Sun Mar 7 18:39:36 2004 @@ -152,7 +152,7 @@ EXPORT_SYMBOL(close_private_file); -void fput(struct file *file) +void fastcall fput(struct file *file) { if (atomic_dec_and_test(&file->f_count)) __fput(file); @@ -163,7 +163,7 @@ /* __fput is called from task context when aio completion releases the last * last use of a struct file *. Do not use otherwise. */ -void __fput(struct file *file) +void fastcall __fput(struct file *file) { struct dentry *dentry = file->f_dentry; struct vfsmount *mnt = file->f_vfsmnt; @@ -192,7 +192,7 @@ mntput(mnt); } -struct file *fget(unsigned int fd) +struct file fastcall *fget(unsigned int fd) { struct file *file; struct files_struct *files = current->files; @@ -214,7 +214,7 @@ * and a flag is returned to be passed to the corresponding fput_light(). * There must not be a cloning between an fget_light/fput_light pair. */ -struct file *fget_light(unsigned int fd, int *fput_needed) +struct file fastcall *fget_light(unsigned int fd, int *fput_needed) { struct file *file; struct files_struct *files = current->files; diff -Nru a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c --- a/fs/freevxfs/vxfs_super.c Sun Mar 7 18:39:38 2004 +++ b/fs/freevxfs/vxfs_super.c Sun Mar 7 18:39:38 2004 @@ -143,6 +143,7 @@ struct vxfs_sb *rsbp; struct buffer_head *bp = NULL; u_long bsize; + struct inode *root; infp = kmalloc(sizeof(*infp), GFP_KERNEL); if (!infp) { @@ -208,8 +209,10 @@ } sbp->s_op = &vxfs_super_ops; - sbp->s_root = d_alloc_root(iget(sbp, VXFS_ROOT_INO)); + root = iget(sbp, VXFS_ROOT_INO); + sbp->s_root = d_alloc_root(root); if (!sbp->s_root) { + iput(root); printk(KERN_WARNING "vxfs: unable to get root dentry.\n"); goto out_free_ilist; } diff -Nru a/fs/hfs/super.c b/fs/hfs/super.c --- a/fs/hfs/super.c Sun Mar 7 18:39:37 2004 +++ b/fs/hfs/super.c Sun Mar 7 18:39:37 2004 @@ -294,13 +294,15 @@ sb->s_root = d_alloc_root(root_inode); if (!sb->s_root) - goto bail_no_root; + goto bail_iput; sb->s_root->d_op = &hfs_dentry_operations; /* everything's okay */ return 0; +bail_iput: + iput(root_inode); bail_no_root: hfs_warn("hfs_fs: get root inode failed.\n"); hfs_mdb_put(sb); diff -Nru a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c --- a/fs/hfsplus/dir.c Sun Mar 7 18:39:36 2004 +++ b/fs/hfsplus/dir.c Sun Mar 7 18:39:36 2004 @@ -399,6 +399,7 @@ res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (!res) { + dentry->d_fsdata = (void *)inode->i_ino; d_instantiate(dentry, inode); mark_inode_dirty(inode); } @@ -424,6 +425,7 @@ return res; } init_special_inode(inode, mode, rdev); + dentry->d_fsdata = (void *)inode->i_ino; d_instantiate(dentry, inode); mark_inode_dirty(inode); diff -Nru a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c --- a/fs/hfsplus/inode.c Sun Mar 7 18:39:37 2004 +++ b/fs/hfsplus/inode.c Sun Mar 7 18:39:37 2004 @@ -335,6 +335,14 @@ init_MUTEX(&HFSPLUS_I(inode).extents_lock); atomic_set(&HFSPLUS_I(inode).opencnt, 0); HFSPLUS_I(inode).flags = 0; + memset(HFSPLUS_I(inode).first_extents, 0, sizeof(hfsplus_extent_rec)); + memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec)); + HFSPLUS_I(inode).alloc_blocks = 0; + HFSPLUS_I(inode).first_blocks = 0; + HFSPLUS_I(inode).cached_start = 0; + HFSPLUS_I(inode).cached_blocks = 0; + HFSPLUS_I(inode).phys_size = 0; + HFSPLUS_I(inode).rsrc_inode = 0; if (S_ISDIR(inode->i_mode)) { inode->i_size = 2; HFSPLUS_SB(sb).folder_count++; @@ -346,14 +354,6 @@ inode->i_fop = &hfsplus_file_operations; inode->i_mapping->a_ops = &hfsplus_aops; HFSPLUS_I(inode).clump_blocks = HFSPLUS_SB(sb).data_clump_blocks; - memset(HFSPLUS_I(inode).first_extents, 0, sizeof(hfsplus_extent_rec)); - memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec)); - HFSPLUS_I(inode).alloc_blocks = 0; - HFSPLUS_I(inode).first_blocks = 0; - HFSPLUS_I(inode).cached_start = 0; - HFSPLUS_I(inode).cached_blocks = 0; - HFSPLUS_I(inode).phys_size = 0; - HFSPLUS_I(inode).rsrc_inode = 0; } else if (S_ISLNK(inode->i_mode)) { HFSPLUS_SB(sb).file_count++; inode->i_op = &page_symlink_inode_operations; diff -Nru a/fs/hfsplus/super.c b/fs/hfsplus/super.c --- a/fs/hfsplus/super.c Sun Mar 7 18:39:36 2004 +++ b/fs/hfsplus/super.c Sun Mar 7 18:39:36 2004 @@ -278,6 +278,7 @@ struct hfsplus_sb_info *sbi; hfsplus_cat_entry entry; struct hfs_find_data fd; + struct inode *root; struct qstr str; int err = -EINVAL; @@ -364,10 +365,12 @@ } /* Load the root directory */ - sb->s_root = d_alloc_root(iget(sb, HFSPLUS_ROOT_CNID)); + root = iget(sb, HFSPLUS_ROOT_CNID); + sb->s_root = d_alloc_root(root); if (!sb->s_root) { if (!silent) printk("HFS+-fs: failed to load root directory\n"); + iput(root); goto cleanup; } diff -Nru a/fs/hpfs/super.c b/fs/hpfs/super.c --- a/fs/hpfs/super.c Sun Mar 7 18:39:37 2004 +++ b/fs/hpfs/super.c Sun Mar 7 18:39:37 2004 @@ -448,6 +448,7 @@ struct hpfs_super_block *superblock; struct hpfs_spare_block *spareblock; struct hpfs_sb_info *sbi; + struct inode *root; uid_t uid; gid_t gid; @@ -613,10 +614,11 @@ brelse(bh0); hpfs_lock_iget(s, 1); - s->s_root = d_alloc_root(iget(s, sbi->sb_root)); + root = iget(s, sbi->sb_root); hpfs_unlock_iget(s); - if (!s->s_root || !s->s_root->d_inode) { - printk("HPFS: iget failed. Why???\n"); + s->s_root = d_alloc_root(root); + if (!s->s_root) { + iput(root); goto bail0; } hpfs_set_dentry_operations(s->s_root); @@ -627,22 +629,24 @@ root_dno = hpfs_fnode_dno(s, sbi->sb_root); if (root_dno) - de = map_dirent(s->s_root->d_inode, root_dno, "\001\001", 2, NULL, &qbh); - if (!root_dno || !de) hpfs_error(s, "unable to find root dir"); + de = map_dirent(root, root_dno, "\001\001", 2, NULL, &qbh); + if (!de) + hpfs_error(s, "unable to find root dir"); else { - s->s_root->d_inode->i_atime.tv_sec = local_to_gmt(s, de->read_date); - s->s_root->d_inode->i_atime.tv_nsec = 0; - s->s_root->d_inode->i_mtime.tv_sec = local_to_gmt(s, de->write_date); - s->s_root->d_inode->i_mtime.tv_nsec = 0; - s->s_root->d_inode->i_ctime.tv_sec = local_to_gmt(s, de->creation_date); - s->s_root->d_inode->i_ctime.tv_nsec = 0; - hpfs_i(s->s_root->d_inode)->i_ea_size = de->ea_size; - hpfs_i(s->s_root->d_inode)->i_parent_dir = s->s_root->d_inode->i_ino; - if (s->s_root->d_inode->i_size == -1) s->s_root->d_inode->i_size = 2048; - if (s->s_root->d_inode->i_blocks == -1) s->s_root->d_inode->i_blocks = 5; + root->i_atime.tv_sec = local_to_gmt(s, de->read_date); + root->i_atime.tv_nsec = 0; + root->i_mtime.tv_sec = local_to_gmt(s, de->write_date); + root->i_mtime.tv_nsec = 0; + root->i_ctime.tv_sec = local_to_gmt(s, de->creation_date); + root->i_ctime.tv_nsec = 0; + hpfs_i(root)->i_ea_size = de->ea_size; + hpfs_i(root)->i_parent_dir = root->i_ino; + if (root->i_size == -1) + root->i_size = 2048; + if (root->i_blocks == -1) + root->i_blocks = 5; + hpfs_brelse4(&qbh); } - if (de) hpfs_brelse4(&qbh); - return 0; bail4: brelse(bh2); diff -Nru a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c --- a/fs/lockd/clntproc.c Sun Mar 7 18:39:36 2004 +++ b/fs/lockd/clntproc.c Sun Mar 7 18:39:36 2004 @@ -195,19 +195,6 @@ } /* - * Wait while server is in grace period - */ -static inline int -nlmclnt_grace_wait(struct nlm_host *host) -{ - if (!host->h_reclaiming) - interruptible_sleep_on_timeout(&host->h_gracewait, 10*HZ); - else - interruptible_sleep_on(&host->h_gracewait); - return signalled()? -ERESTARTSYS : 0; -} - -/* * Allocate an NLM RPC call struct */ struct nlm_rqst * diff -Nru a/fs/namei.c b/fs/namei.c --- a/fs/namei.c Sun Mar 7 18:39:37 2004 +++ b/fs/namei.c Sun Mar 7 18:39:37 2004 @@ -571,7 +571,7 @@ * * We expect 'base' to be positive and a directory. */ -int link_path_walk(const char * name, struct nameidata *nd) +int fastcall link_path_walk(const char * name, struct nameidata *nd) { struct path next; struct inode *inode; @@ -771,7 +771,7 @@ return err; } -int path_walk(const char * name, struct nameidata *nd) +int fastcall path_walk(const char * name, struct nameidata *nd) { current->total_link_count = 0; return link_path_walk(name, nd); @@ -858,7 +858,7 @@ return 1; } -int path_lookup(const char *name, unsigned int flags, struct nameidata *nd) +int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd) { nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags; @@ -971,7 +971,7 @@ * that namei follows links, while lnamei does not. * SMP-safe */ -int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) +int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) { char *tmp = getname(name); int err = PTR_ERR(tmp); diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c --- a/fs/nfsd/export.c Sun Mar 7 18:39:37 2004 +++ b/fs/nfsd/export.c Sun Mar 7 18:39:37 2004 @@ -56,11 +56,6 @@ #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) static struct cache_head *expkey_table[EXPKEY_HASHMAX]; -static inline int key_len(int type) -{ - return type == 0 ? 8 : type == 1 ? 4 : 12; -} - static inline int svc_expkey_hash(struct svc_expkey *item) { int hash = item->ek_fsidtype; @@ -547,8 +542,8 @@ mk_fsid_v0(fsidv, dev, ino); return exp_find_key(clp, 0, fsidv, NULL); } - mk_fsid_v2(fsidv, dev, ino); - return exp_find_key(clp, 2, fsidv, NULL); + mk_fsid_v3(fsidv, dev, ino); + return exp_find_key(clp, 3, fsidv, NULL); } /* @@ -684,8 +679,8 @@ mk_fsid_v0(fsid, dev, inode->i_ino); return exp_set_key(clp, 0, fsid, exp); } - mk_fsid_v2(fsid, dev, inode->i_ino); - return exp_set_key(clp, 2, fsid, exp); + mk_fsid_v3(fsid, dev, inode->i_ino); + return exp_set_key(clp, 3, fsid, exp); } static void exp_unhash(struct svc_export *exp) diff -Nru a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c --- a/fs/nfsd/nfsfh.c Sun Mar 7 18:39:37 2004 +++ b/fs/nfsd/nfsfh.c Sun Mar 7 18:39:37 2004 @@ -117,19 +117,14 @@ case 0: break; default: goto out; } - - switch (fh->fh_fsid_type) { - case 0: - len = 2; - break; - case 1: - len = 1; - break; - case 2: + len = key_len(fh->fh_fsid_type) / 4; + if (len == 0) goto out; + if (fh->fh_fsid_type == 2) { + /* deprecated, convert to type 3 */ len = 3; - break; - default: - goto out; + fh->fh_fsid_type = 3; + fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1]))); + fh->fh_fsid[1] = fh->fh_fsid[2]; } if ((data_left -= len)<0) goto out; exp = exp_find(rqstp->rq_client, fh->fh_fsid_type, datap, &rqstp->rq_chandle); @@ -336,19 +331,31 @@ parent->d_name.name, dentry->d_name.name, (inode ? inode->i_ino : 0)); - /* for large devnums rules are simple */ - if (!old_valid_dev(ex_dev)) { - ref_fh_version = 1; - if (exp->ex_flags & NFSEXP_FSID) - ref_fh_fsid_type = 1; - else - ref_fh_fsid_type = 2; - } else if (ref_fh) { + if (ref_fh) { ref_fh_version = ref_fh->fh_handle.fh_version; - ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; - if (!(exp->ex_flags & NFSEXP_FSID) || ref_fh_fsid_type == 2) + if (ref_fh_version == 0xca) + ref_fh_fsid_type = 0; + else + ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; + if (ref_fh_fsid_type > 3) ref_fh_fsid_type = 0; } + /* make sure ref_fh type works for given export */ + if (ref_fh_fsid_type == 1 && + !(exp->ex_flags & NFSEXP_FSID)) { + /* if we don't have an fsid, we cannot provide one... */ + ref_fh_fsid_type = 0; + } + if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) { + /* for newer device numbers, we must use a newer fsid format */ + ref_fh_version = 1; + ref_fh_fsid_type = 3; + } + if (old_valid_dev(ex_dev) && + (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3)) + /* must use type1 for smaller device numbers */ + ref_fh_fsid_type = 0; + if (ref_fh == fhp) fh_put(ref_fh); @@ -376,16 +383,23 @@ if (inode) _fh_update_old(dentry, exp, &fhp->fh_handle); } else { + int len; fhp->fh_handle.fh_version = 1; fhp->fh_handle.fh_auth_type = 0; datap = fhp->fh_handle.fh_auth+0; fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; switch (ref_fh_fsid_type) { + case 0: + /* + * fsid_type 0: + * 2byte major, 2byte minor, 4byte inode + */ + mk_fsid_v0(datap, ex_dev, + exp->ex_dentry->d_inode->i_ino); + break; case 1: /* fsid_type 1 == 4 bytes filesystem id */ mk_fsid_v1(datap, exp->ex_fsid); - datap += 1; - fhp->fh_handle.fh_size = 2*4; break; case 2: /* @@ -394,21 +408,22 @@ */ mk_fsid_v2(datap, ex_dev, exp->ex_dentry->d_inode->i_ino); - datap += 3; - fhp->fh_handle.fh_size = 4*4; break; - default: + case 3: /* - * fsid_type 0: - * 2byte major, 2byte minor, 4byte inode + * fsid_type 3: + * 4byte devicenumber, 4byte inode */ - mk_fsid_v0(datap, ex_dev, + mk_fsid_v3(datap, ex_dev, exp->ex_dentry->d_inode->i_ino); - datap += 2; - fhp->fh_handle.fh_size = 3*4; + break; } + len = key_len(ref_fh_fsid_type); + datap += len/4; + fhp->fh_handle.fh_size = 4 + len; + if (inode) { - int size = fhp->fh_maxsize/4 - 3; + int size = (fhp->fh_maxsize-len-4)/4; fhp->fh_handle.fh_fileid_type = _fh_update(dentry, exp, datap, &size); fhp->fh_handle.fh_size += size*4; diff -Nru a/fs/open.c b/fs/open.c --- a/fs/open.c Sun Mar 7 18:39:36 2004 +++ b/fs/open.c Sun Mar 7 18:39:36 2004 @@ -890,7 +890,7 @@ files->next_fd = fd; } -void put_unused_fd(unsigned int fd) +void fastcall put_unused_fd(unsigned int fd) { struct files_struct *files = current->files; spin_lock(&files->file_lock); @@ -913,7 +913,7 @@ * will follow. */ -void fd_install(unsigned int fd, struct file * file) +void fastcall fd_install(unsigned int fd, struct file * file) { struct files_struct *files = current->files; spin_lock(&files->file_lock); diff -Nru a/fs/romfs/inode.c b/fs/romfs/inode.c --- a/fs/romfs/inode.c Sun Mar 7 18:39:37 2004 +++ b/fs/romfs/inode.c Sun Mar 7 18:39:37 2004 @@ -115,6 +115,7 @@ { struct buffer_head *bh; struct romfs_super_block *rsb; + struct inode *root; int sz; /* I would parse the options here, but there are none.. :) */ @@ -154,23 +155,25 @@ strnlen(rsb->name, ROMFS_MAXFN) + 1 + ROMFH_PAD) & ROMFH_MASK; - brelse(bh); - s->s_op = &romfs_ops; + root = iget(s, sz); + if (!root) + goto out; + s->s_root = d_alloc_root(iget(s, sz)); if (!s->s_root) - goto outnobh; + goto outiput; + + brelse(bh); + return 0; - /* Ehrhm; sorry.. :) And thanks to Hans-Joachim Widmaier :) */ - if (0) { +outiput: + iput(root); out: - brelse(bh); + brelse(bh); outnobh: - return -EINVAL; - } - - return 0; + return -EINVAL; } /* That's simple too. */ diff -Nru a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c --- a/fs/xfs/linux/xfs_super.c Sun Mar 7 18:39:38 2004 +++ b/fs/xfs/linux/xfs_super.c Sun Mar 7 18:39:38 2004 @@ -247,7 +247,7 @@ { struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip)); - filemap_fdatawrite(inode->i_mapping); + filemap_flush(inode->i_mapping); } void diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c --- a/fs/xfs/xfs_log.c Sun Mar 7 18:39:38 2004 +++ b/fs/xfs/xfs_log.c Sun Mar 7 18:39:38 2004 @@ -1227,7 +1227,7 @@ kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); iclog = *iclogp; iclog->hic_data = (xlog_in_core_2_t *) - kmem_alloc(iclogsize, KM_SLEEP); + kmem_zalloc(iclogsize, KM_SLEEP); iclog->ic_prev = prev_iclog; prev_iclog = iclog; diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h Sun Mar 7 18:39:37 2004 +++ b/include/acpi/acconfig.h Sun Mar 7 18:39:37 2004 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20040211 +#define ACPI_CA_VERSION 0x20040220 /* Maximum objects in the various object caches */ diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- a/include/acpi/acglobal.h Sun Mar 7 18:39:36 2004 +++ b/include/acpi/acglobal.h Sun Mar 7 18:39:36 2004 @@ -57,6 +57,12 @@ #define ACPI_EXTERN extern #endif +/* + * Keep local copies of these FADT-based registers. NOTE: These globals + * are first in this file for alignment reasons on 64-bit systems. + */ +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; /***************************************************************************** * @@ -97,6 +103,11 @@ ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT; ACPI_EXTERN FACS_DESCRIPTOR *acpi_gbl_FACS; ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; +/* + * Since there may be multiple SSDTs and PSDTS, a single pointer is not + * sufficient; Therefore, there isn't one! + */ + /* * Handle both ACPI 1.0 and ACPI 2.0 Integer widths @@ -107,17 +118,6 @@ ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; -/* Keep local copies of these FADT-based registers */ - -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; -ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; - -/* - * Since there may be multiple SSDTs and PSDTS, a single pointer is not - * sufficient; Therefore, there isn't one! - */ - - /* * ACPI Table info arrays */ @@ -165,7 +165,8 @@ extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; extern const u8 acpi_gbl_decode_to8bit[8]; -extern const char *acpi_gbl_db_sleep_states[ACPI_S_STATE_COUNT]; +extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; +extern const char *acpi_gbl_highest_dstate_names[4]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h Sun Mar 7 18:39:37 2004 +++ b/include/acpi/actypes.h Sun Mar 7 18:39:37 2004 @@ -880,7 +880,8 @@ { ACPI_COMMON_OBJ_INFO; - u32 valid; /* Indicates which fields are valid */ + u8 highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */ + u32 valid; /* Indicates which fields below are valid */ u32 current_status; /* _STA value */ acpi_integer address; /* _ADR value if any */ struct acpi_device_id hardware_id; /* _HID value if any */ diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h --- a/include/acpi/acutils.h Sun Mar 7 18:39:36 2004 +++ b/include/acpi/acutils.h Sun Mar 7 18:39:36 2004 @@ -508,6 +508,10 @@ struct acpi_namespace_node *device_node, struct acpi_device_id *uid); +acpi_status +acpi_ut_execute_sxds ( + struct acpi_namespace_node *device_node, + u8 *highest); /* * ut_mutex - mutual exclusion interfaces diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h --- a/include/asm-i386/acpi.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-i386/acpi.h Sun Mar 7 18:39:38 2004 @@ -110,6 +110,7 @@ extern int acpi_lapic; extern int acpi_ioapic; extern int acpi_noirq; +extern int acpi_strict; /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ #define FIX_ACPI_PAGES 4 diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h --- a/include/asm-i386/fixmap.h Sun Mar 7 18:39:36 2004 +++ b/include/asm-i386/fixmap.h Sun Mar 7 18:39:36 2004 @@ -71,6 +71,9 @@ FIX_ACPI_BEGIN, FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, #endif +#ifdef CONFIG_PCI_MMCONFIG + FIX_PCIE_MCFG, +#endif __end_of_permanent_fixed_addresses, /* temporary boot-time mappings, used before ioremap() is functional */ #define NR_FIX_BTMAPS 16 diff -Nru a/include/asm-i386/linkage.h b/include/asm-i386/linkage.h --- a/include/asm-i386/linkage.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-i386/linkage.h Sun Mar 7 18:39:38 2004 @@ -3,6 +3,7 @@ #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) #define FASTCALL(x) x __attribute__((regparm(3))) +#define fastcall __attribute__((regparm(3))) #ifdef CONFIG_X86_ALIGNMENT_16 #define __ALIGN .align 16,0x90 diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h --- a/include/asm-i386/smp.h Sun Mar 7 18:39:37 2004 +++ b/include/asm-i386/smp.h Sun Mar 7 18:39:37 2004 @@ -38,7 +38,6 @@ extern void smp_flush_tlb(void); extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); -extern void smp_send_reschedule(int cpu); extern void smp_invalidate_rcv(void); /* Process an NMI */ extern void (*mtrr_hook) (void); extern void zap_low_mappings (void); diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h --- a/include/asm-ia64/acpi.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-ia64/acpi.h Sun Mar 7 18:39:38 2004 @@ -88,6 +88,8 @@ #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ ((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr)) +#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ + const char *acpi_get_sysname (void); int acpi_request_vector (u32 int_type); int acpi_register_irq (u32 gsi, u32 polarity, u32 trigger); diff -Nru a/include/asm-ppc64/iSeries/vio.h b/include/asm-ppc64/iSeries/vio.h --- a/include/asm-ppc64/iSeries/vio.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-ppc64/iSeries/vio.h Sun Mar 7 18:39:38 2004 @@ -127,4 +127,8 @@ viorc_openRejected = 0x0301 }; +struct device; + +extern struct device *iSeries_vio_dev; + #endif /* _ISERIES_VIO_H */ diff -Nru a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h --- a/include/asm-ppc64/mmu.h Sun Mar 7 18:39:37 2004 +++ b/include/asm-ppc64/mmu.h Sun Mar 7 18:39:37 2004 @@ -18,14 +18,24 @@ #ifndef __ASSEMBLY__ -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; +/* Time to allow for more things here */ +typedef unsigned long mm_context_id_t; +typedef struct { + mm_context_id_t id; +#ifdef CONFIG_HUGETLB_PAGE + int low_hpages; +#endif +} mm_context_t; #ifdef CONFIG_HUGETLB_PAGE -#define CONTEXT_LOW_HPAGES (1UL<<63) +#define KERNEL_LOW_HPAGES .low_hpages = 0, #else -#define CONTEXT_LOW_HPAGES 0 +#define KERNEL_LOW_HPAGES #endif + +#define KERNEL_CONTEXT(ea) ({ \ + mm_context_t ctx = { .id = REGION_ID(ea), KERNEL_LOW_HPAGES}; \ + ctx; }) /* * Hardware Segment Lookaside Buffer Entry diff -Nru a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h --- a/include/asm-ppc64/mmu_context.h Sun Mar 7 18:39:37 2004 +++ b/include/asm-ppc64/mmu_context.h Sun Mar 7 18:39:37 2004 @@ -52,7 +52,7 @@ long head; long tail; long size; - mm_context_t elements[LAST_USER_CONTEXT]; + mm_context_id_t elements[LAST_USER_CONTEXT]; }; extern struct mmu_context_queue_t mmu_context_queue; @@ -83,7 +83,6 @@ long head; unsigned long flags; /* This does the right thing across a fork (I hope) */ - unsigned long low_hpages = mm->context & CONTEXT_LOW_HPAGES; spin_lock_irqsave(&mmu_context_queue.lock, flags); @@ -93,8 +92,7 @@ } head = mmu_context_queue.head; - mm->context = mmu_context_queue.elements[head]; - mm->context |= low_hpages; + mm->context.id = mmu_context_queue.elements[head]; head = (head < LAST_USER_CONTEXT-1) ? head+1 : 0; mmu_context_queue.head = head; @@ -132,8 +130,7 @@ #endif mmu_context_queue.size++; - mmu_context_queue.elements[index] = - mm->context & ~CONTEXT_LOW_HPAGES; + mmu_context_queue.elements[index] = mm->context.id; spin_unlock_irqrestore(&mmu_context_queue.lock, flags); } @@ -211,8 +208,6 @@ get_vsid( unsigned long context, unsigned long ea ) { unsigned long ordinal, vsid; - - context &= ~CONTEXT_LOW_HPAGES; ordinal = (((ea >> 28) & 0x1fffff) * LAST_USER_CONTEXT) | context; vsid = (ordinal * VSID_RANDOMIZER) & VSID_MASK; diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h --- a/include/asm-ppc64/page.h Sun Mar 7 18:39:36 2004 +++ b/include/asm-ppc64/page.h Sun Mar 7 18:39:36 2004 @@ -32,6 +32,7 @@ /* For 64-bit processes the hugepage range is 1T-1.5T */ #define TASK_HPAGE_BASE (0x0000010000000000UL) #define TASK_HPAGE_END (0x0000018000000000UL) + /* For 32-bit processes the hugepage range is 2-3G */ #define TASK_HPAGE_BASE_32 (0x80000000UL) #define TASK_HPAGE_END_32 (0xc0000000UL) @@ -39,7 +40,7 @@ #define ARCH_HAS_HUGEPAGE_ONLY_RANGE #define is_hugepage_only_range(addr, len) \ ( ((addr > (TASK_HPAGE_BASE-len)) && (addr < TASK_HPAGE_END)) || \ - ((current->mm->context & CONTEXT_LOW_HPAGES) && \ + (current->mm->context.low_hpages && \ (addr > (TASK_HPAGE_BASE_32-len)) && (addr < TASK_HPAGE_END_32)) ) #define hugetlb_free_pgtables free_pgtables #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA @@ -47,7 +48,7 @@ #define in_hugepage_area(context, addr) \ ((cur_cpu_spec->cpu_features & CPU_FTR_16M_PAGE) && \ ((((addr) >= TASK_HPAGE_BASE) && ((addr) < TASK_HPAGE_END)) || \ - (((context) & CONTEXT_LOW_HPAGES) && \ + ((context).low_hpages && \ (((addr) >= TASK_HPAGE_BASE_32) && ((addr) < TASK_HPAGE_END_32))))) #else /* !CONFIG_HUGETLB_PAGE */ diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h --- a/include/asm-sparc/system.h Sun Mar 7 18:39:37 2004 +++ b/include/asm-sparc/system.h Sun Mar 7 18:39:37 2004 @@ -75,7 +75,7 @@ #ifdef CONFIG_SMP #define SWITCH_ENTER(prv) \ do { \ - if (test_tsk_thread_flag(prv, TIF_USEDFPU) { \ + if (test_tsk_thread_flag(prv, TIF_USEDFPU)) { \ put_psr(get_psr() | PSR_EF); \ fpsave(&(prv)->thread.float_regs[0], &(prv)->thread.fsr, \ &(prv)->thread.fpqueue[0], &(prv)->thread.fpqdepth); \ diff -Nru a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h --- a/include/asm-sparc/thread_info.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-sparc/thread_info.h Sun Mar 7 18:39:38 2004 @@ -79,9 +79,9 @@ /* * thread information allocation */ -#ifdef CONFIG_SUN4 +#if PAGE_SHIFT == 13 #define THREAD_INFO_ORDER 0 -#else +#else /* PAGE_SHIFT */ #define THREAD_INFO_ORDER 1 #endif diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h --- a/include/asm-sparc/unistd.h Sun Mar 7 18:39:36 2004 +++ b/include/asm-sparc/unistd.h Sun Mar 7 18:39:36 2004 @@ -461,7 +461,6 @@ unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff); -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on); struct sigaction; asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, diff -Nru a/include/asm-um/linkage.h b/include/asm-um/linkage.h --- a/include/asm-um/linkage.h Sun Mar 7 18:39:38 2004 +++ b/include/asm-um/linkage.h Sun Mar 7 18:39:38 2004 @@ -2,5 +2,6 @@ #define __ASM_LINKAGE_H #define FASTCALL(x) x __attribute__((regparm(3))) +#define fastcall __attribute__((regparm(3))) #endif diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h --- a/include/asm-x86_64/acpi.h Sun Mar 7 18:39:37 2004 +++ b/include/asm-x86_64/acpi.h Sun Mar 7 18:39:37 2004 @@ -104,6 +104,7 @@ extern int acpi_lapic; extern int acpi_ioapic; extern int acpi_noirq; +extern int acpi_strict; /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */ #define FIX_ACPI_PAGES 4 diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h --- a/include/linux/acpi.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/acpi.h Sun Mar 7 18:39:36 2004 @@ -233,8 +233,27 @@ } __attribute__ ((packed)); /* + * Simple Boot Flags + * http://www.microsoft.com/whdc/hwdev/resources/specs/simp_bios.mspx + */ +struct acpi_table_sbf +{ + u8 sbf_signature[4]; + u32 sbf_len; + u8 sbf_revision; + u8 sbf_csum; + u8 sbf_oemid[6]; + u8 sbf_oemtable[8]; + u8 sbf_revdata[4]; + u8 sbf_creator[4]; + u8 sbf_crearev[4]; + u8 sbf_cmos; + u8 sbf_spare[3]; +} __attribute__ ((packed)); + +/* * System Resource Affinity Table (SRAT) - * see http://www.microsoft.com/hwdev/design/srat.htm + * http://www.microsoft.com/whdc/hwdev/platform/proc/SRAT.mspx */ struct acpi_table_srat { @@ -317,6 +336,15 @@ char ec_id[0]; } __attribute__ ((packed)); +/* PCI MMCONFIG */ + +struct acpi_table_mcfg { + struct acpi_table_header header; + u8 reserved[8]; + u32 base_address; + u32 base_reserved; +} __attribute__ ((packed)); + /* Table Handlers */ enum acpi_table_id { @@ -338,6 +366,7 @@ ACPI_SSDT, ACPI_SPMI, ACPI_HPET, + ACPI_MCFG, ACPI_TABLE_COUNT }; @@ -368,6 +397,10 @@ void acpi_numa_arch_fixup(void); extern int acpi_mp_config; + +extern u32 pci_mmcfg_base_addr; + +extern int sbf_port ; #else /*!CONFIG_ACPI_BOOT*/ diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/blkdev.h Sun Mar 7 18:39:36 2004 @@ -372,6 +372,8 @@ #define blk_queue_plugged(q) !list_empty(&(q)->plug_list) #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) +#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) + #define blk_fs_request(rq) ((rq)->flags & REQ_CMD) #define blk_pc_request(rq) ((rq)->flags & REQ_BLOCK_PC) #define blk_noretry_request(rq) ((rq)->flags & REQ_FAILFAST) diff -Nru a/include/linux/compat.h b/include/linux/compat.h --- a/include/linux/compat.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/compat.h Sun Mar 7 18:39:37 2004 @@ -45,7 +45,7 @@ extern int cp_compat_stat(struct kstat *, struct compat_stat *); extern int get_compat_timespec(struct timespec *, const struct compat_timespec *); -extern int put_compat_timespec(struct timespec *, const struct compat_timespec *); +extern int put_compat_timespec(const struct timespec *, struct compat_timespec *); struct compat_iovec { compat_uptr_t iov_base; diff -Nru a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h --- a/include/linux/compat_ioctl.h Sun Mar 7 18:39:38 2004 +++ b/include/linux/compat_ioctl.h Sun Mar 7 18:39:38 2004 @@ -122,7 +122,6 @@ COMPATIBLE_IOCTL(STOP_ARRAY_RO) COMPATIBLE_IOCTL(RESTART_ARRAY_RW) /* DM */ -#ifdef CONFIG_DM_IOCTL_V4 COMPATIBLE_IOCTL(DM_VERSION) COMPATIBLE_IOCTL(DM_LIST_DEVICES) COMPATIBLE_IOCTL(DM_DEV_CREATE) @@ -135,19 +134,6 @@ COMPATIBLE_IOCTL(DM_TABLE_CLEAR) COMPATIBLE_IOCTL(DM_TABLE_DEPS) COMPATIBLE_IOCTL(DM_TABLE_STATUS) -#else -COMPATIBLE_IOCTL(DM_VERSION) -COMPATIBLE_IOCTL(DM_REMOVE_ALL) -COMPATIBLE_IOCTL(DM_DEV_CREATE) -COMPATIBLE_IOCTL(DM_DEV_REMOVE) -COMPATIBLE_IOCTL(DM_DEV_RELOAD) -COMPATIBLE_IOCTL(DM_DEV_SUSPEND) -COMPATIBLE_IOCTL(DM_DEV_RENAME) -COMPATIBLE_IOCTL(DM_DEV_DEPS) -COMPATIBLE_IOCTL(DM_DEV_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_STATUS) -COMPATIBLE_IOCTL(DM_TARGET_WAIT) -#endif /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) diff -Nru a/include/linux/dm-ioctl-v1.h b/include/linux/dm-ioctl-v1.h --- a/include/linux/dm-ioctl-v1.h Sun Mar 7 18:39:38 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef _LINUX_DM_IOCTL_V1_H -#define _LINUX_DM_IOCTL_V1_H - -#include - -#define DM_DIR "mapper" /* Slashes not supported */ -#define DM_MAX_TYPE_NAME 16 -#define DM_NAME_LEN 128 -#define DM_UUID_LEN 129 - -/* - * Implements a traditional ioctl interface to the device mapper. - */ - -/* - * All ioctl arguments consist of a single chunk of memory, with - * this structure at the start. If a uuid is specified any - * lookup (eg. for a DM_INFO) will be done on that, *not* the - * name. - */ -struct dm_ioctl { - /* - * The version number is made up of three parts: - * major - no backward or forward compatibility, - * minor - only backwards compatible, - * patch - both backwards and forwards compatible. - * - * All clients of the ioctl interface should fill in the - * version number of the interface that they were - * compiled with. - * - * All recognised ioctl commands (ie. those that don't - * return -ENOTTY) fill out this field, even if the - * command failed. - */ - uint32_t version[3]; /* in/out */ - uint32_t data_size; /* total size of data passed in - * including this struct */ - - uint32_t data_start; /* offset to start of data - * relative to start of this struct */ - - uint32_t target_count; /* in/out */ - uint32_t open_count; /* out */ - uint32_t flags; /* in/out */ - - __kernel_old_dev_t dev; /* in/out */ - - char name[DM_NAME_LEN]; /* device name */ - char uuid[DM_UUID_LEN]; /* unique identifier for - * the block device */ -}; - -/* - * Used to specify tables. These structures appear after the - * dm_ioctl. - */ -struct dm_target_spec { - int32_t status; /* used when reading from kernel only */ - uint64_t sector_start; - uint32_t length; - - /* - * Offset in bytes (from the start of this struct) to - * next target_spec. - */ - uint32_t next; - - char target_type[DM_MAX_TYPE_NAME]; - - /* - * Parameter string starts immediately after this object. - * Be careful to add padding after string to ensure correct - * alignment of subsequent dm_target_spec. - */ -}; - -/* - * Used to retrieve the target dependencies. - */ -struct dm_target_deps { - uint32_t count; - - __kernel_old_dev_t dev[0]; /* out */ -}; - -/* - * If you change this make sure you make the corresponding change - * to dm-ioctl.c:lookup_ioctl() - */ -enum { - /* Top level cmds */ - DM_VERSION_CMD = 0, - DM_REMOVE_ALL_CMD, - - /* device level cmds */ - DM_DEV_CREATE_CMD, - DM_DEV_REMOVE_CMD, - DM_DEV_RELOAD_CMD, - DM_DEV_RENAME_CMD, - DM_DEV_SUSPEND_CMD, - DM_DEV_DEPS_CMD, - DM_DEV_STATUS_CMD, - - /* target level cmds */ - DM_TARGET_STATUS_CMD, - DM_TARGET_WAIT_CMD -}; - -#define DM_IOCTL 0xfd - -#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl) -#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl) - -#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl) -#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl) -#define DM_DEV_RELOAD _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD, struct dm_ioctl) -#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl) -#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl) -#define DM_DEV_DEPS _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD, struct dm_ioctl) -#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl) - -#define DM_TARGET_STATUS _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD, struct dm_ioctl) -#define DM_TARGET_WAIT _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD, struct dm_ioctl) - -#define DM_VERSION_MAJOR 1 -#define DM_VERSION_MINOR 0 -#define DM_VERSION_PATCHLEVEL 6 -#define DM_VERSION_EXTRA "-ioctl (2002-10-15)" - -/* Status bits */ -#define DM_READONLY_FLAG 0x00000001 -#define DM_SUSPEND_FLAG 0x00000002 -#define DM_EXISTS_FLAG 0x00000004 -#define DM_PERSISTENT_DEV_FLAG 0x00000008 - -/* - * Flag passed into ioctl STATUS command to get table information - * rather than current status. - */ -#define DM_STATUS_TABLE_FLAG 0x00000010 - -#endif /* _LINUX_DM_IOCTL_H */ diff -Nru a/include/linux/dm-ioctl-v4.h b/include/linux/dm-ioctl-v4.h --- a/include/linux/dm-ioctl-v4.h Sun Mar 7 18:39:36 2004 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef _LINUX_DM_IOCTL_V4_H -#define _LINUX_DM_IOCTL_V4_H - -#include - -#define DM_DIR "mapper" /* Slashes not supported */ -#define DM_MAX_TYPE_NAME 16 -#define DM_NAME_LEN 128 -#define DM_UUID_LEN 129 - -/* - * A traditional ioctl interface for the device mapper. - * - * Each device can have two tables associated with it, an - * 'active' table which is the one currently used by io passing - * through the device, and an 'inactive' one which is a table - * that is being prepared as a replacement for the 'active' one. - * - * DM_VERSION: - * Just get the version information for the ioctl interface. - * - * DM_REMOVE_ALL: - * Remove all dm devices, destroy all tables. Only really used - * for debug. - * - * DM_LIST_DEVICES: - * Get a list of all the dm device names. - * - * DM_DEV_CREATE: - * Create a new device, neither the 'active' or 'inactive' table - * slots will be filled. The device will be in suspended state - * after creation, however any io to the device will get errored - * since it will be out-of-bounds. - * - * DM_DEV_REMOVE: - * Remove a device, destroy any tables. - * - * DM_DEV_RENAME: - * Rename a device. - * - * DM_SUSPEND: - * This performs both suspend and resume, depending which flag is - * passed in. - * Suspend: This command will not return until all pending io to - * the device has completed. Further io will be deferred until - * the device is resumed. - * Resume: It is no longer an error to issue this command on an - * unsuspended device. If a table is present in the 'inactive' - * slot, it will be moved to the active slot, then the old table - * from the active slot will be _destroyed_. Finally the device - * is resumed. - * - * DM_DEV_STATUS: - * Retrieves the status for the table in the 'active' slot. - * - * DM_DEV_WAIT: - * Wait for a significant event to occur to the device. This - * could either be caused by an event triggered by one of the - * targets of the table in the 'active' slot, or a table change. - * - * DM_TABLE_LOAD: - * Load a table into the 'inactive' slot for the device. The - * device does _not_ need to be suspended prior to this command. - * - * DM_TABLE_CLEAR: - * Destroy any table in the 'inactive' slot (ie. abort). - * - * DM_TABLE_DEPS: - * Return a set of device dependencies for the 'active' table. - * - * DM_TABLE_STATUS: - * Return the targets status for the 'active' table. - */ - -/* - * All ioctl arguments consist of a single chunk of memory, with - * this structure at the start. If a uuid is specified any - * lookup (eg. for a DM_INFO) will be done on that, *not* the - * name. - */ -struct dm_ioctl { - /* - * The version number is made up of three parts: - * major - no backward or forward compatibility, - * minor - only backwards compatible, - * patch - both backwards and forwards compatible. - * - * All clients of the ioctl interface should fill in the - * version number of the interface that they were - * compiled with. - * - * All recognised ioctl commands (ie. those that don't - * return -ENOTTY) fill out this field, even if the - * command failed. - */ - uint32_t version[3]; /* in/out */ - uint32_t data_size; /* total size of data passed in - * including this struct */ - - uint32_t data_start; /* offset to start of data - * relative to start of this struct */ - - uint32_t target_count; /* in/out */ - int32_t open_count; /* out */ - uint32_t flags; /* in/out */ - uint32_t event_nr; /* in/out */ - uint32_t padding; - - uint64_t dev; /* in/out */ - - char name[DM_NAME_LEN]; /* device name */ - char uuid[DM_UUID_LEN]; /* unique identifier for - * the block device */ -}; - -/* - * Used to specify tables. These structures appear after the - * dm_ioctl. - */ -struct dm_target_spec { - uint64_t sector_start; - uint64_t length; - int32_t status; /* used when reading from kernel only */ - - /* - * Offset in bytes (from the start of this struct) to - * next target_spec. - */ - uint32_t next; - - char target_type[DM_MAX_TYPE_NAME]; - - /* - * Parameter string starts immediately after this object. - * Be careful to add padding after string to ensure correct - * alignment of subsequent dm_target_spec. - */ -}; - -/* - * Used to retrieve the target dependencies. - */ -struct dm_target_deps { - uint32_t count; /* Array size */ - uint32_t padding; /* unused */ - uint64_t dev[0]; /* out */ -}; - -/* - * Used to get a list of all dm devices. - */ -struct dm_name_list { - uint64_t dev; - uint32_t next; /* offset to the next record from - the _start_ of this */ - char name[0]; -}; - -/* - * If you change this make sure you make the corresponding change - * to dm-ioctl.c:lookup_ioctl() - */ -enum { - /* Top level cmds */ - DM_VERSION_CMD = 0, - DM_REMOVE_ALL_CMD, - DM_LIST_DEVICES_CMD, - - /* device level cmds */ - DM_DEV_CREATE_CMD, - DM_DEV_REMOVE_CMD, - DM_DEV_RENAME_CMD, - DM_DEV_SUSPEND_CMD, - DM_DEV_STATUS_CMD, - DM_DEV_WAIT_CMD, - - /* Table level cmds */ - DM_TABLE_LOAD_CMD, - DM_TABLE_CLEAR_CMD, - DM_TABLE_DEPS_CMD, - DM_TABLE_STATUS_CMD, -}; - -#define DM_IOCTL 0xfd - -#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl) -#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl) -#define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl) - -#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl) -#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl) -#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl) -#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl) -#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl) -#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl) - -#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl) -#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl) -#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) -#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) - -#define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 0 -#define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2003-06-04)" - -/* Status bits */ -#define DM_READONLY_FLAG (1 << 0) /* In/Out */ -#define DM_SUSPEND_FLAG (1 << 1) /* In/Out */ -#define DM_PERSISTENT_DEV_FLAG (1 << 3) /* In */ - -/* - * Flag passed into ioctl STATUS command to get table information - * rather than current status. - */ -#define DM_STATUS_TABLE_FLAG (1 << 4) /* In */ - -/* - * Flags that indicate whether a table is present in either of - * the two table slots that a device has. - */ -#define DM_ACTIVE_PRESENT_FLAG (1 << 5) /* Out */ -#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */ - -/* - * Indicates that the buffer passed in wasn't big enough for the - * results. - */ -#define DM_BUFFER_FULL_FLAG (1 << 8) /* Out */ - -#endif /* _LINUX_DM_IOCTL_H */ diff -Nru a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h --- a/include/linux/dm-ioctl.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/dm-ioctl.h Sun Mar 7 18:39:36 2004 @@ -1,18 +1,237 @@ /* - * Copyright (C) 2003 Sistina Software (UK) Limited. + * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited. * * This file is released under the LGPL. */ -#ifndef _LINUX_DM_IOCTL_H -#define _LINUX_DM_IOCTL_H +#ifndef _LINUX_DM_IOCTL_V4_H +#define _LINUX_DM_IOCTL_V4_H -#include +#include -#ifdef CONFIG_DM_IOCTL_V4 -#include "dm-ioctl-v4.h" -#else -#include "dm-ioctl-v1.h" -#endif +#define DM_DIR "mapper" /* Slashes not supported */ +#define DM_MAX_TYPE_NAME 16 +#define DM_NAME_LEN 128 +#define DM_UUID_LEN 129 -#endif +/* + * A traditional ioctl interface for the device mapper. + * + * Each device can have two tables associated with it, an + * 'active' table which is the one currently used by io passing + * through the device, and an 'inactive' one which is a table + * that is being prepared as a replacement for the 'active' one. + * + * DM_VERSION: + * Just get the version information for the ioctl interface. + * + * DM_REMOVE_ALL: + * Remove all dm devices, destroy all tables. Only really used + * for debug. + * + * DM_LIST_DEVICES: + * Get a list of all the dm device names. + * + * DM_DEV_CREATE: + * Create a new device, neither the 'active' or 'inactive' table + * slots will be filled. The device will be in suspended state + * after creation, however any io to the device will get errored + * since it will be out-of-bounds. + * + * DM_DEV_REMOVE: + * Remove a device, destroy any tables. + * + * DM_DEV_RENAME: + * Rename a device. + * + * DM_SUSPEND: + * This performs both suspend and resume, depending which flag is + * passed in. + * Suspend: This command will not return until all pending io to + * the device has completed. Further io will be deferred until + * the device is resumed. + * Resume: It is no longer an error to issue this command on an + * unsuspended device. If a table is present in the 'inactive' + * slot, it will be moved to the active slot, then the old table + * from the active slot will be _destroyed_. Finally the device + * is resumed. + * + * DM_DEV_STATUS: + * Retrieves the status for the table in the 'active' slot. + * + * DM_DEV_WAIT: + * Wait for a significant event to occur to the device. This + * could either be caused by an event triggered by one of the + * targets of the table in the 'active' slot, or a table change. + * + * DM_TABLE_LOAD: + * Load a table into the 'inactive' slot for the device. The + * device does _not_ need to be suspended prior to this command. + * + * DM_TABLE_CLEAR: + * Destroy any table in the 'inactive' slot (ie. abort). + * + * DM_TABLE_DEPS: + * Return a set of device dependencies for the 'active' table. + * + * DM_TABLE_STATUS: + * Return the targets status for the 'active' table. + */ + +/* + * All ioctl arguments consist of a single chunk of memory, with + * this structure at the start. If a uuid is specified any + * lookup (eg. for a DM_INFO) will be done on that, *not* the + * name. + */ +struct dm_ioctl { + /* + * The version number is made up of three parts: + * major - no backward or forward compatibility, + * minor - only backwards compatible, + * patch - both backwards and forwards compatible. + * + * All clients of the ioctl interface should fill in the + * version number of the interface that they were + * compiled with. + * + * All recognised ioctl commands (ie. those that don't + * return -ENOTTY) fill out this field, even if the + * command failed. + */ + uint32_t version[3]; /* in/out */ + uint32_t data_size; /* total size of data passed in + * including this struct */ + + uint32_t data_start; /* offset to start of data + * relative to start of this struct */ + + uint32_t target_count; /* in/out */ + int32_t open_count; /* out */ + uint32_t flags; /* in/out */ + uint32_t event_nr; /* in/out */ + uint32_t padding; + + uint64_t dev; /* in/out */ + + char name[DM_NAME_LEN]; /* device name */ + char uuid[DM_UUID_LEN]; /* unique identifier for + * the block device */ +}; + +/* + * Used to specify tables. These structures appear after the + * dm_ioctl. + */ +struct dm_target_spec { + uint64_t sector_start; + uint64_t length; + int32_t status; /* used when reading from kernel only */ + + /* + * Offset in bytes (from the start of this struct) to + * next target_spec. + */ + uint32_t next; + + char target_type[DM_MAX_TYPE_NAME]; + + /* + * Parameter string starts immediately after this object. + * Be careful to add padding after string to ensure correct + * alignment of subsequent dm_target_spec. + */ +}; + +/* + * Used to retrieve the target dependencies. + */ +struct dm_target_deps { + uint32_t count; /* Array size */ + uint32_t padding; /* unused */ + uint64_t dev[0]; /* out */ +}; + +/* + * Used to get a list of all dm devices. + */ +struct dm_name_list { + uint64_t dev; + uint32_t next; /* offset to the next record from + the _start_ of this */ + char name[0]; +}; + +/* + * If you change this make sure you make the corresponding change + * to dm-ioctl.c:lookup_ioctl() + */ +enum { + /* Top level cmds */ + DM_VERSION_CMD = 0, + DM_REMOVE_ALL_CMD, + DM_LIST_DEVICES_CMD, + + /* device level cmds */ + DM_DEV_CREATE_CMD, + DM_DEV_REMOVE_CMD, + DM_DEV_RENAME_CMD, + DM_DEV_SUSPEND_CMD, + DM_DEV_STATUS_CMD, + DM_DEV_WAIT_CMD, + + /* Table level cmds */ + DM_TABLE_LOAD_CMD, + DM_TABLE_CLEAR_CMD, + DM_TABLE_DEPS_CMD, + DM_TABLE_STATUS_CMD, +}; + +#define DM_IOCTL 0xfd + +#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl) +#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl) +#define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl) + +#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl) +#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl) +#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl) +#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl) +#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl) +#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl) + +#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl) +#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl) +#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) +#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) + +#define DM_VERSION_MAJOR 4 +#define DM_VERSION_MINOR 0 +#define DM_VERSION_PATCHLEVEL 0 +#define DM_VERSION_EXTRA "-ioctl (2003-06-04)" + +/* Status bits */ +#define DM_READONLY_FLAG (1 << 0) /* In/Out */ +#define DM_SUSPEND_FLAG (1 << 1) /* In/Out */ +#define DM_PERSISTENT_DEV_FLAG (1 << 3) /* In */ + +/* + * Flag passed into ioctl STATUS command to get table information + * rather than current status. + */ +#define DM_STATUS_TABLE_FLAG (1 << 4) /* In */ + +/* + * Flags that indicate whether a table is present in either of + * the two table slots that a device has. + */ +#define DM_ACTIVE_PRESENT_FLAG (1 << 5) /* Out */ +#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */ + +/* + * Indicates that the buffer passed in wasn't big enough for the + * results. + */ +#define DM_BUFFER_FULL_FLAG (1 << 8) /* Out */ + +#endif /* _LINUX_DM_IOCTL_H */ diff -Nru a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h --- a/include/linux/i2o-dev.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/i2o-dev.h Sun Mar 7 18:39:36 2004 @@ -182,7 +182,7 @@ { u32 adapter_id; u32 parent_tid:12; - u32 tate:4; + u32 state:4; u32 bus_num:8; u32 bus_type:8; union diff -Nru a/include/linux/i2o.h b/include/linux/i2o.h --- a/include/linux/i2o.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/i2o.h Sun Mar 7 18:39:36 2004 @@ -544,6 +544,25 @@ #define I2O_DSC_DEVICE_BUSY 0x001B #define I2O_DSC_DEVICE_NOT_AVAILABLE 0x001C +/* DetailedStatusCode defines for Block Storage Operation: Table 6-7 Detailed + Status Codes.*/ + +#define I2O_BSA_DSC_SUCCESS 0x0000 +#define I2O_BSA_DSC_MEDIA_ERROR 0x0001 +#define I2O_BSA_DSC_ACCESS_ERROR 0x0002 +#define I2O_BSA_DSC_DEVICE_FAILURE 0x0003 +#define I2O_BSA_DSC_DEVICE_NOT_READY 0x0004 +#define I2O_BSA_DSC_MEDIA_NOT_PRESENT 0x0005 +#define I2O_BSA_DSC_MEDIA_LOCKED 0x0006 +#define I2O_BSA_DSC_MEDIA_FAILURE 0x0007 +#define I2O_BSA_DSC_PROTOCOL_FAILURE 0x0008 +#define I2O_BSA_DSC_BUS_FAILURE 0x0009 +#define I2O_BSA_DSC_ACCESS_VIOLATION 0x000A +#define I2O_BSA_DSC_WRITE_PROTECTED 0x000B +#define I2O_BSA_DSC_DEVICE_RESET 0x000C +#define I2O_BSA_DSC_VOLUME_CHANGED 0x000D +#define I2O_BSA_DSC_TIMEOUT 0x000E + /* FailureStatusCodes, Table 3-3 Message Failure Codes */ #define I2O_FSC_TRANSPORT_SERVICE_SUSPENDED 0x81 diff -Nru a/include/linux/linkage.h b/include/linux/linkage.h --- a/include/linux/linkage.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/linkage.h Sun Mar 7 18:39:37 2004 @@ -37,6 +37,7 @@ #ifndef FASTCALL #define FASTCALL(x) x +#define fastcall #endif #endif diff -Nru a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h --- a/include/linux/nfsd/nfsfh.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/nfsd/nfsfh.h Sun Mar 7 18:39:37 2004 @@ -66,8 +66,9 @@ * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number * NOTE: we cannot use the kdev_t device id value, because kdev_t.h * says we mustn't. We must break it up and reassemble. - * Possible future encodings: * 1 - 4 byte user specified identifier + * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED + * 3 - 4 byte device id, encoded for user-space, 4 byte inode number * * The fileid_type identified how the file within the filesystem is encoded. * This is (will be) passed to, and set by, the underlying filesystem if it supports @@ -114,6 +115,7 @@ #define fh_auth_type fh_base.fh_new.fb_auth_type #define fh_fileid_type fh_base.fh_new.fb_fileid_type #define fh_auth fh_base.fh_new.fb_auth +#define fh_fsid fh_base.fh_new.fb_auth #ifdef __KERNEL__ @@ -181,6 +183,23 @@ fsidv[0] = htonl(MAJOR(dev)); fsidv[1] = htonl(MINOR(dev)); fsidv[2] = ino_t_to_u32(ino); +} + +static inline void mk_fsid_v3(u32 *fsidv, dev_t dev, ino_t ino) +{ + fsidv[0] = new_encode_dev(dev); + fsidv[1] = ino_t_to_u32(ino); +} + +static inline int key_len(int type) +{ + switch(type) { + case 0: return 8; + case 1: return 4; + case 2: return 12; + case 3: return 8; + default: return 0; + } } /* diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/pci_ids.h Sun Mar 7 18:39:37 2004 @@ -1808,6 +1808,7 @@ #define PCI_VENDOR_ID_AFAVLAB 0x14db #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 +#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 #define PCI_VENDOR_ID_BROADCOM 0x14e4 #define PCI_DEVICE_ID_TIGON3_5700 0x1644 diff -Nru a/include/linux/sched.h b/include/linux/sched.h --- a/include/linux/sched.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/sched.h Sun Mar 7 18:39:36 2004 @@ -602,7 +602,7 @@ extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state)); extern int FASTCALL(wake_up_process(struct task_struct * tsk)); #ifdef CONFIG_SMP - extern void FASTCALL(kick_process(struct task_struct * tsk)); + extern void kick_process(struct task_struct *tsk); #else static inline void kick_process(struct task_struct *tsk) { } #endif diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h --- a/include/linux/serial_core.h Sun Mar 7 18:39:36 2004 +++ b/include/linux/serial_core.h Sun Mar 7 18:39:36 2004 @@ -84,6 +84,7 @@ #include #include #include +#include struct uart_port; struct uart_info; diff -Nru a/include/linux/smp.h b/include/linux/smp.h --- a/include/linux/smp.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/smp.h Sun Mar 7 18:39:37 2004 @@ -30,7 +30,7 @@ /* * sends a 'reschedule' event to another CPU: */ -extern void FASTCALL(smp_send_reschedule(int cpu)); +extern void smp_send_reschedule(int cpu); /* diff -Nru a/include/linux/syscalls.h b/include/linux/syscalls.h --- a/include/linux/syscalls.h Sun Mar 7 18:39:38 2004 +++ b/include/linux/syscalls.h Sun Mar 7 18:39:38 2004 @@ -386,24 +386,24 @@ unsigned int count); asmlinkage long sys_setsockopt(int fd, int level, int optname, - char *optval, int optlen); + char __user *optval, int optlen); asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen); -asmlinkage long sys_bind(int, struct sockaddr *, int); -asmlinkage long sys_connect(int, struct sockaddr *, int); -asmlinkage long sys_accept(int, struct sockaddr *, int *); -asmlinkage long sys_getsockname(int, struct sockaddr *, int *); -asmlinkage long sys_getpeername(int, struct sockaddr *, int *); -asmlinkage long sys_send(int, void *, size_t, unsigned); -asmlinkage long sys_sendto(int, void *, size_t, unsigned, - struct sockaddr *, int); +asmlinkage long sys_bind(int, struct sockaddr __user *, int); +asmlinkage long sys_connect(int, struct sockaddr __user *, int); +asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); +asmlinkage long sys_send(int, void __user *, size_t, unsigned); +asmlinkage long sys_sendto(int, void __user *, size_t, unsigned, + struct sockaddr __user *, int); asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); -asmlinkage long sys_recv(int, void *, size_t, unsigned); -asmlinkage long sys_recvfrom(int, void *, size_t, unsigned, - struct sockaddr *, int *); +asmlinkage long sys_recv(int, void __user *, size_t, unsigned); +asmlinkage long sys_recvfrom(int, void __user *, size_t, unsigned, + struct sockaddr __user *, int __user *); asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); asmlinkage long sys_socket(int, int, int); -asmlinkage long sys_socketpair(int, int, int, int [2]); +asmlinkage long sys_socketpair(int, int, int, int __user *); asmlinkage long sys_socketcall(int call, unsigned long __user *args); asmlinkage long sys_listen(int, int); asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h --- a/include/linux/sysctl.h Sun Mar 7 18:39:37 2004 +++ b/include/linux/sysctl.h Sun Mar 7 18:39:37 2004 @@ -321,6 +321,7 @@ NET_TCP_LOW_LATENCY=93, NET_IPV4_IPFRAG_SECRET_INTERVAL=94, NET_TCP_WESTWOOD=95, + NET_IPV4_IGMP_MAX_MSF=96, }; enum { diff -Nru a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h --- a/include/net/bluetooth/hci.h Sun Mar 7 18:39:38 2004 +++ b/include/net/bluetooth/hci.h Sun Mar 7 18:39:38 2004 @@ -35,21 +35,31 @@ #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) /* HCI dev events */ -#define HCI_DEV_REG 1 -#define HCI_DEV_UNREG 2 -#define HCI_DEV_UP 3 -#define HCI_DEV_DOWN 4 -#define HCI_DEV_SUSPEND 5 -#define HCI_DEV_RESUME 6 +#define HCI_DEV_REG 1 +#define HCI_DEV_UNREG 2 +#define HCI_DEV_UP 3 +#define HCI_DEV_DOWN 4 +#define HCI_DEV_SUSPEND 5 +#define HCI_DEV_RESUME 6 + +/* HCI notify events */ +#define HCI_NOTIFY_CONN_ADD 1 +#define HCI_NOTIFY_CONN_DEL 2 +#define HCI_NOTIFY_VOICE_SETTING 3 /* HCI device types */ #define HCI_VHCI 0 #define HCI_USB 1 #define HCI_PCCARD 2 -#define HCI_UART 3 -#define HCI_RS232 4 +#define HCI_UART 3 +#define HCI_RS232 4 #define HCI_PCI 5 +/* HCI device quirks */ +enum { + HCI_QUIRK_RESET_ON_INIT +}; + /* HCI device flags */ enum { HCI_UP, @@ -90,24 +100,24 @@ #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ -#define HCI_CONN_TIMEOUT (HZ * 40) -#define HCI_DISCONN_TIMEOUT (HZ * 2) +#define HCI_CONN_TIMEOUT (HZ * 40) +#define HCI_DISCONN_TIMEOUT (HZ * 2) #define HCI_CONN_IDLE_TIMEOUT (HZ * 60) /* HCI Packet types */ #define HCI_COMMAND_PKT 0x01 -#define HCI_ACLDATA_PKT 0x02 -#define HCI_SCODATA_PKT 0x03 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 #define HCI_EVENT_PKT 0x04 #define HCI_UNKNOWN_PKT 0xff /* HCI Packet types */ -#define HCI_DM1 0x0008 -#define HCI_DM3 0x0400 -#define HCI_DM5 0x4000 -#define HCI_DH1 0x0010 -#define HCI_DH3 0x0800 -#define HCI_DH5 0x8000 +#define HCI_DM1 0x0008 +#define HCI_DM3 0x0400 +#define HCI_DM5 0x4000 +#define HCI_DH1 0x0010 +#define HCI_DH3 0x0800 +#define HCI_DH5 0x8000 #define HCI_HV1 0x0020 #define HCI_HV2 0x0040 diff -Nru a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h --- a/include/net/bluetooth/hci_core.h Sun Mar 7 18:39:37 2004 +++ b/include/net/bluetooth/hci_core.h Sun Mar 7 18:39:37 2004 @@ -77,6 +77,8 @@ __u16 link_policy; __u16 link_mode; + unsigned long quirks; + atomic_t cmd_cnt; unsigned int acl_cnt; unsigned int sco_cnt; @@ -128,6 +130,7 @@ int (*flush)(struct hci_dev *hdev); int (*send)(struct sk_buff *skb); void (*destruct)(struct hci_dev *hdev); + void (*notify)(struct hci_dev *hdev, unsigned int evt); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); }; diff -Nru a/kernel/compat.c b/kernel/compat.c --- a/kernel/compat.c Sun Mar 7 18:39:37 2004 +++ b/kernel/compat.c Sun Mar 7 18:39:37 2004 @@ -30,7 +30,7 @@ __get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; } -int put_compat_timespec(struct timespec *ts, const struct compat_timespec *cts) +int put_compat_timespec(const struct timespec *ts, struct compat_timespec *cts) { return (verify_area(VERIFY_WRITE, cts, sizeof(*cts)) || __put_user(ts->tv_sec, &cts->tv_sec) || diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Sun Mar 7 18:39:38 2004 +++ b/kernel/exit.c Sun Mar 7 18:39:38 2004 @@ -386,7 +386,7 @@ } } -void put_files_struct(struct files_struct *files) +void fastcall put_files_struct(struct files_struct *files) { if (atomic_dec_and_test(&files->count)) { close_files(files); @@ -810,7 +810,7 @@ do_exit((error_code&0xff)<<8); } -task_t *next_thread(task_t *p) +task_t fastcall *next_thread(task_t *p) { struct pid_link *link = p->pids + PIDTYPE_TGID; struct list_head *tmp, *head = &link->pidptr->task_list; diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Sun Mar 7 18:39:36 2004 +++ b/kernel/fork.c Sun Mar 7 18:39:36 2004 @@ -91,7 +91,7 @@ free_task(tsk); } -void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) +void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; @@ -103,7 +103,7 @@ EXPORT_SYMBOL(add_wait_queue); -void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait) +void fastcall add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; @@ -115,7 +115,7 @@ EXPORT_SYMBOL(add_wait_queue_exclusive); -void remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) +void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; @@ -139,7 +139,7 @@ * stops them from bleeding out - it would still allow subsequent * loads to move into the the critical region). */ -void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) +void fastcall prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) { unsigned long flags; @@ -153,7 +153,7 @@ EXPORT_SYMBOL(prepare_to_wait); -void +void fastcall prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state) { unsigned long flags; @@ -168,7 +168,7 @@ EXPORT_SYMBOL(prepare_to_wait_exclusive); -void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) +void fastcall finish_wait(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; @@ -418,7 +418,7 @@ * is dropped: either by a lazy thread or by * mmput. Free the page directory and the mm. */ -void __mmdrop(struct mm_struct *mm) +void fastcall __mmdrop(struct mm_struct *mm) { BUG_ON(mm == &init_mm); mm_free_pgd(mm); diff -Nru a/kernel/pid.c b/kernel/pid.c --- a/kernel/pid.c Sun Mar 7 18:39:37 2004 +++ b/kernel/pid.c Sun Mar 7 18:39:37 2004 @@ -57,7 +57,7 @@ static spinlock_t pidmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; -inline void free_pidmap(int pid) +fastcall void free_pidmap(int pid) { pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE; int offset = pid & BITS_PER_PAGE_MASK; @@ -146,7 +146,7 @@ return -1; } -inline struct pid *find_pid(enum pid_type type, int nr) +fastcall struct pid *find_pid(enum pid_type type, int nr) { struct list_head *elem, *bucket = &pid_hash[type][pid_hashfn(nr)]; struct pid *pid; @@ -159,14 +159,14 @@ return NULL; } -void link_pid(task_t *task, struct pid_link *link, struct pid *pid) +void fastcall link_pid(task_t *task, struct pid_link *link, struct pid *pid) { atomic_inc(&pid->count); list_add_tail(&link->pid_chain, &pid->task_list); link->pidptr = pid; } -int attach_pid(task_t *task, enum pid_type type, int nr) +int fastcall attach_pid(task_t *task, enum pid_type type, int nr) { struct pid *pid = find_pid(type, nr); @@ -209,7 +209,7 @@ __detach_pid(task, type); } -void detach_pid(task_t *task, enum pid_type type) +void fastcall detach_pid(task_t *task, enum pid_type type) { int nr = __detach_pid(task, type); diff -Nru a/kernel/rcupdate.c b/kernel/rcupdate.c --- a/kernel/rcupdate.c Sun Mar 7 18:39:36 2004 +++ b/kernel/rcupdate.c Sun Mar 7 18:39:36 2004 @@ -66,7 +66,7 @@ * The read-side of critical section that use call_rcu() for updation must * be protected by rcu_read_lock()/rcu_read_unlock(). */ -void call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg) +void fastcall call_rcu(struct rcu_head *head, void (*func)(void *arg), void *arg) { int cpu; unsigned long flags; diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Sun Mar 7 18:39:38 2004 +++ b/kernel/sched.c Sun Mar 7 18:39:38 2004 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -700,7 +701,7 @@ return success; } -int wake_up_process(task_t * p) +int fastcall wake_up_process(task_t * p) { return try_to_wake_up(p, TASK_STOPPED | TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE, 0); @@ -708,7 +709,7 @@ EXPORT_SYMBOL(wake_up_process); -int wake_up_state(task_t *p, unsigned int state) +int fastcall wake_up_state(task_t *p, unsigned int state) { return try_to_wake_up(p, state, 0); } @@ -717,7 +718,7 @@ * Perform scheduler related setup for a newly forked process p. * p is forked by current. */ -void sched_fork(task_t *p) +void fastcall sched_fork(task_t *p) { /* * We mark the process as running here, but have not actually @@ -773,7 +774,7 @@ * This function will do some initial scheduler statistics housekeeping * that must be done for every newly created process. */ -void wake_up_forked_process(task_t * p) +void fastcall wake_up_forked_process(task_t * p) { unsigned long flags; runqueue_t *rq = task_rq_lock(current, &flags); @@ -817,7 +818,7 @@ * artificially, because any timeslice recovered here * was given away by the parent in the first place.) */ -void sched_exit(task_t * p) +void fastcall sched_exit(task_t * p) { unsigned long flags; runqueue_t *rq; @@ -1796,7 +1797,7 @@ * @mode: which threads * @nr_exclusive: how many wake-one or wake-many threads to wake up */ -void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) +void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) { unsigned long flags; @@ -1810,7 +1811,7 @@ /* * Same as __wake_up but called with the spinlock in wait_queue_head_t held. */ -void __wake_up_locked(wait_queue_head_t *q, unsigned int mode) +void fastcall __wake_up_locked(wait_queue_head_t *q, unsigned int mode) { __wake_up_common(q, mode, 1, 0); } @@ -1828,7 +1829,7 @@ * * On UP it can prevent extra preemption. */ -void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) +void fastcall __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) { unsigned long flags; @@ -1845,7 +1846,7 @@ EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ -void complete(struct completion *x) +void fastcall complete(struct completion *x) { unsigned long flags; @@ -1858,7 +1859,7 @@ EXPORT_SYMBOL(complete); -void complete_all(struct completion *x) +void fastcall complete_all(struct completion *x) { unsigned long flags; @@ -1869,7 +1870,7 @@ spin_unlock_irqrestore(&x->wait.lock, flags); } -void wait_for_completion(struct completion *x) +void fastcall wait_for_completion(struct completion *x) { might_sleep(); spin_lock_irq(&x->wait.lock); @@ -1907,7 +1908,7 @@ __remove_wait_queue(q, &wait); \ spin_unlock_irqrestore(&q->lock, flags); -void interruptible_sleep_on(wait_queue_head_t *q) +void fastcall interruptible_sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1920,7 +1921,7 @@ EXPORT_SYMBOL(interruptible_sleep_on); -long interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) +long fastcall interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR @@ -1935,7 +1936,7 @@ EXPORT_SYMBOL(interruptible_sleep_on_timeout); -void sleep_on(wait_queue_head_t *q) +void fastcall sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1948,7 +1949,7 @@ EXPORT_SYMBOL(sleep_on); -long sleep_on_timeout(wait_queue_head_t *q, long timeout) +long fastcall sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR diff -Nru a/kernel/signal.c b/kernel/signal.c --- a/kernel/signal.c Sun Mar 7 18:39:37 2004 +++ b/kernel/signal.c Sun Mar 7 18:39:37 2004 @@ -213,7 +213,7 @@ #define PENDING(p,b) has_pending_signals(&(p)->signal, (b)) -inline void recalc_sigpending_tsk(struct task_struct *t) +fastcall void recalc_sigpending_tsk(struct task_struct *t) { if (t->signal->group_stop_count > 0 || PENDING(&t->pending, &t->blocked) || diff -Nru a/kernel/softirq.c b/kernel/softirq.c --- a/kernel/softirq.c Sun Mar 7 18:39:37 2004 +++ b/kernel/softirq.c Sun Mar 7 18:39:37 2004 @@ -130,7 +130,7 @@ /* * This function must run with irqs disabled! */ -inline void raise_softirq_irqoff(unsigned int nr) +inline fastcall void raise_softirq_irqoff(unsigned int nr) { __raise_softirq_irqoff(nr); @@ -149,7 +149,7 @@ EXPORT_SYMBOL(raise_softirq_irqoff); -void raise_softirq(unsigned int nr) +void fastcall raise_softirq(unsigned int nr) { unsigned long flags; @@ -179,7 +179,7 @@ static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec) = { NULL }; static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec) = { NULL }; -void __tasklet_schedule(struct tasklet_struct *t) +void fastcall __tasklet_schedule(struct tasklet_struct *t) { unsigned long flags; @@ -192,7 +192,7 @@ EXPORT_SYMBOL(__tasklet_schedule); -void __tasklet_hi_schedule(struct tasklet_struct *t) +void fastcall __tasklet_hi_schedule(struct tasklet_struct *t) { unsigned long flags; diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Sun Mar 7 18:39:38 2004 +++ b/kernel/timer.c Sun Mar 7 18:39:38 2004 @@ -997,7 +997,7 @@ * * In all cases the return value is guaranteed to be non-negative. */ -signed long schedule_timeout(signed long timeout) +fastcall signed long schedule_timeout(signed long timeout) { struct timer_list timer; unsigned long expire; diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c --- a/kernel/workqueue.c Sun Mar 7 18:39:38 2004 +++ b/kernel/workqueue.c Sun Mar 7 18:39:38 2004 @@ -78,7 +78,7 @@ * We queue the work to the CPU it was submitted, but there is no * guarantee that it will be processed by that CPU. */ -int queue_work(struct workqueue_struct *wq, struct work_struct *work) +int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) { int ret = 0, cpu = get_cpu(); @@ -99,7 +99,7 @@ __queue_work(wq->cpu_wq + smp_processor_id(), work); } -int queue_delayed_work(struct workqueue_struct *wq, +int fastcall queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay) { int ret = 0; @@ -203,7 +203,7 @@ * This function used to run the workqueues itself. Now we just wait for the * helper threads to do it. */ -void flush_workqueue(struct workqueue_struct *wq) +void fastcall flush_workqueue(struct workqueue_struct *wq) { struct cpu_workqueue_struct *cwq; int cpu; @@ -310,12 +310,12 @@ static struct workqueue_struct *keventd_wq; -int schedule_work(struct work_struct *work) +int fastcall schedule_work(struct work_struct *work) { return queue_work(keventd_wq, work); } -int schedule_delayed_work(struct work_struct *work, unsigned long delay) +int fastcall schedule_delayed_work(struct work_struct *work, unsigned long delay) { return queue_delayed_work(keventd_wq, work, delay); } diff -Nru a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c --- a/lib/rwsem-spinlock.c Sun Mar 7 18:39:36 2004 +++ b/lib/rwsem-spinlock.c Sun Mar 7 18:39:36 2004 @@ -29,7 +29,7 @@ /* * initialise the semaphore */ -void init_rwsem(struct rw_semaphore *sem) +void fastcall init_rwsem(struct rw_semaphore *sem) { sem->activity = 0; spin_lock_init(&sem->wait_lock); @@ -117,7 +117,7 @@ /* * get a read lock on the semaphore */ -void __down_read(struct rw_semaphore *sem) +void fastcall __down_read(struct rw_semaphore *sem) { struct rwsem_waiter waiter; struct task_struct *tsk; @@ -162,7 +162,7 @@ /* * trylock for reading -- returns 1 if successful, 0 if contention */ -int __down_read_trylock(struct rw_semaphore *sem) +int fastcall __down_read_trylock(struct rw_semaphore *sem) { int ret = 0; rwsemtrace(sem,"Entering __down_read_trylock"); @@ -185,7 +185,7 @@ * get a write lock on the semaphore * - note that we increment the waiting count anyway to indicate an exclusive lock */ -void __down_write(struct rw_semaphore *sem) +void fastcall __down_write(struct rw_semaphore *sem) { struct rwsem_waiter waiter; struct task_struct *tsk; @@ -230,7 +230,7 @@ /* * trylock for writing -- returns 1 if successful, 0 if contention */ -int __down_write_trylock(struct rw_semaphore *sem) +int fastcall __down_write_trylock(struct rw_semaphore *sem) { int ret = 0; rwsemtrace(sem,"Entering __down_write_trylock"); @@ -252,7 +252,7 @@ /* * release a read lock on the semaphore */ -void __up_read(struct rw_semaphore *sem) +void fastcall __up_read(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering __up_read"); @@ -269,7 +269,7 @@ /* * release a write lock on the semaphore */ -void __up_write(struct rw_semaphore *sem) +void fastcall __up_write(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering __up_write"); @@ -288,7 +288,7 @@ * downgrade a write lock into a read lock * - just wake up any readers at the front of the queue */ -void __downgrade_write(struct rw_semaphore *sem) +void fastcall __downgrade_write(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering __downgrade_write"); diff -Nru a/lib/rwsem.c b/lib/rwsem.c --- a/lib/rwsem.c Sun Mar 7 18:39:36 2004 +++ b/lib/rwsem.c Sun Mar 7 18:39:36 2004 @@ -162,7 +162,7 @@ /* * wait for the read lock to be granted */ -struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem) +struct rw_semaphore fastcall *rwsem_down_read_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; @@ -178,7 +178,7 @@ /* * wait for the write lock to be granted */ -struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem) +struct rw_semaphore fastcall *rwsem_down_write_failed(struct rw_semaphore *sem) { struct rwsem_waiter waiter; @@ -195,7 +195,7 @@ * handle waking up a waiter on the semaphore * - up_read has decremented the active part of the count if we come here */ -struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem) +struct rw_semaphore fastcall *rwsem_wake(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering rwsem_wake"); @@ -217,7 +217,7 @@ * - caller incremented waiting part of count, and discovered it to be still negative * - just wake up any readers at the front of the queue */ -struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) +struct rw_semaphore fastcall *rwsem_downgrade_wake(struct rw_semaphore *sem) { rwsemtrace(sem,"Entering rwsem_downgrade_wake"); diff -Nru a/mm/filemap.c b/mm/filemap.c --- a/mm/filemap.c Sun Mar 7 18:39:37 2004 +++ b/mm/filemap.c Sun Mar 7 18:39:37 2004 @@ -292,7 +292,7 @@ return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)]; } -void wait_on_page_bit(struct page *page, int bit_nr) +void fastcall wait_on_page_bit(struct page *page, int bit_nr) { wait_queue_head_t *waitqueue = page_waitqueue(page); DEFINE_WAIT(wait); @@ -324,7 +324,7 @@ * the clear_bit and the read of the waitqueue (to avoid SMP races with a * parallel wait_on_page_locked()). */ -void unlock_page(struct page *page) +void fastcall unlock_page(struct page *page) { wait_queue_head_t *waitqueue = page_waitqueue(page); smp_mb__before_clear_bit(); @@ -365,7 +365,7 @@ * chances are that on the second loop, the block layer's plug list is empty, * so sync_page() will then return in state TASK_UNINTERRUPTIBLE. */ -void __lock_page(struct page *page) +void fastcall __lock_page(struct page *page) { wait_queue_head_t *wqh = page_waitqueue(page); DEFINE_WAIT(wait); @@ -953,7 +953,7 @@ * and schedules an I/O to read in its contents from disk. */ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset)); -static int page_cache_read(struct file * file, unsigned long offset) +static int fastcall page_cache_read(struct file * file, unsigned long offset) { struct address_space *mapping = file->f_mapping; struct page *page; diff -Nru a/mm/highmem.c b/mm/highmem.c --- a/mm/highmem.c Sun Mar 7 18:39:37 2004 +++ b/mm/highmem.c Sun Mar 7 18:39:37 2004 @@ -147,7 +147,7 @@ return vaddr; } -void *kmap_high(struct page *page) +void fastcall *kmap_high(struct page *page) { unsigned long vaddr; @@ -170,7 +170,7 @@ EXPORT_SYMBOL(kmap_high); -void kunmap_high(struct page *page) +void fastcall kunmap_high(struct page *page) { unsigned long vaddr; unsigned long nr; diff -Nru a/mm/memory.c b/mm/memory.c --- a/mm/memory.c Sun Mar 7 18:39:37 2004 +++ b/mm/memory.c Sun Mar 7 18:39:37 2004 @@ -145,7 +145,7 @@ } while (--nr); } -pte_t * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address) +pte_t fastcall * pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address) { if (!pmd_present(*pmd)) { struct page *new; @@ -171,7 +171,7 @@ return pte_offset_map(pmd, address); } -pte_t * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address) +pte_t fastcall * pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsigned long address) { if (!pmd_present(*pmd)) { pte_t *new; @@ -1646,7 +1646,7 @@ * On a two-level page table, this ends up actually being entirely * optimized away. */ -pmd_t *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +pmd_t fastcall *__pmd_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) { pmd_t *new; diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c --- a/mm/page_alloc.c Sun Mar 7 18:39:36 2004 +++ b/mm/page_alloc.c Sun Mar 7 18:39:36 2004 @@ -443,7 +443,7 @@ * Free a 0-order page */ static void FASTCALL(free_hot_cold_page(struct page *page, int cold)); -static void free_hot_cold_page(struct page *page, int cold) +static void fastcall free_hot_cold_page(struct page *page, int cold) { struct zone *zone = page_zone(page); struct per_cpu_pages *pcp; @@ -462,12 +462,12 @@ put_cpu(); } -void free_hot_page(struct page *page) +void fastcall free_hot_page(struct page *page) { free_hot_cold_page(page, 0); } -void free_cold_page(struct page *page) +void fastcall free_cold_page(struct page *page) { free_hot_cold_page(page, 1); } @@ -532,7 +532,7 @@ * sized machine, GFP_HIGHMEM and GFP_KERNEL requests basically leave the DMA * zone untouched. */ -struct page * +struct page * fastcall __alloc_pages(unsigned int gfp_mask, unsigned int order, struct zonelist *zonelist) { @@ -685,7 +685,7 @@ /* * Common helper functions. */ -unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order) +fastcall unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order) { struct page * page; @@ -697,7 +697,7 @@ EXPORT_SYMBOL(__get_free_pages); -unsigned long get_zeroed_page(unsigned int gfp_mask) +fastcall unsigned long get_zeroed_page(unsigned int gfp_mask) { struct page * page; @@ -726,7 +726,7 @@ free_hot_cold_page(pvec->pages[i], pvec->cold); } -void __free_pages(struct page *page, unsigned int order) +fastcall void __free_pages(struct page *page, unsigned int order) { if (!PageReserved(page) && put_page_testzero(page)) { if (order == 0) @@ -738,7 +738,7 @@ EXPORT_SYMBOL(__free_pages); -void free_pages(unsigned long addr, unsigned int order) +fastcall void free_pages(unsigned long addr, unsigned int order) { if (addr != 0) { BUG_ON(!virt_addr_valid(addr)); diff -Nru a/mm/rmap.c b/mm/rmap.c --- a/mm/rmap.c Sun Mar 7 18:39:38 2004 +++ b/mm/rmap.c Sun Mar 7 18:39:38 2004 @@ -112,7 +112,7 @@ * If the page has a single-entry pte_chain, collapse that back to a PageDirect * representation. This way, it's only done under memory pressure. */ -int page_referenced(struct page * page) +int fastcall page_referenced(struct page * page) { struct pte_chain *pc; int referenced = 0; @@ -165,7 +165,7 @@ * Add a new pte reverse mapping to a page. * The caller needs to hold the mm->page_table_lock. */ -struct pte_chain * +struct pte_chain * fastcall page_add_rmap(struct page *page, pte_t *ptep, struct pte_chain *pte_chain) { pte_addr_t pte_paddr = ptep_to_paddr(ptep); @@ -221,7 +221,7 @@ * the page. * Caller needs to hold the mm->page_table_lock. */ -void page_remove_rmap(struct page *page, pte_t *ptep) +void fastcall page_remove_rmap(struct page *page, pte_t *ptep) { pte_addr_t pte_paddr = ptep_to_paddr(ptep); struct pte_chain *pc; @@ -293,7 +293,7 @@ * mm->page_table_lock try_to_unmap_one(), trylock */ static int FASTCALL(try_to_unmap_one(struct page *, pte_addr_t)); -static int try_to_unmap_one(struct page * page, pte_addr_t paddr) +static int fastcall try_to_unmap_one(struct page * page, pte_addr_t paddr) { pte_t *ptep = rmap_ptep_map(paddr); unsigned long address = ptep_to_address(ptep); @@ -382,7 +382,7 @@ * SWAP_AGAIN - we missed a trylock, try again later * SWAP_FAIL - the page is unswappable */ -int try_to_unmap(struct page * page) +int fastcall try_to_unmap(struct page * page) { struct pte_chain *pc, *next_pc, *start; int ret = SWAP_SUCCESS; diff -Nru a/mm/slab.c b/mm/slab.c --- a/mm/slab.c Sun Mar 7 18:39:37 2004 +++ b/mm/slab.c Sun Mar 7 18:39:38 2004 @@ -2134,7 +2134,7 @@ * * Currently only used for dentry validation. */ -int kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) +int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr) { unsigned long addr = (unsigned long) ptr; unsigned long min_addr = PAGE_OFFSET; diff -Nru a/mm/swap.c b/mm/swap.c --- a/mm/swap.c Sun Mar 7 18:39:37 2004 +++ b/mm/swap.c Sun Mar 7 18:39:37 2004 @@ -76,7 +76,7 @@ /* * FIXME: speed this up? */ -void activate_page(struct page *page) +void fastcall activate_page(struct page *page) { struct zone *zone = page_zone(page); @@ -97,7 +97,7 @@ * inactive,referenced -> active,unreferenced * active,unreferenced -> active,referenced */ -void mark_page_accessed(struct page *page) +void fastcall mark_page_accessed(struct page *page) { if (!PageActive(page) && PageReferenced(page) && PageLRU(page)) { activate_page(page); @@ -116,7 +116,7 @@ static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, }; static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, }; -void lru_cache_add(struct page *page) +void fastcall lru_cache_add(struct page *page) { struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); @@ -126,7 +126,7 @@ put_cpu_var(lru_add_pvecs); } -void lru_cache_add_active(struct page *page) +void fastcall lru_cache_add_active(struct page *page) { struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs); @@ -152,7 +152,7 @@ * This path almost never happens for VM activity - pages are normally * freed via pagevecs. But it gets used by networking. */ -void __page_cache_release(struct page *page) +void fastcall __page_cache_release(struct page *page) { unsigned long flags; struct zone *zone = page_zone(page); diff -Nru a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c --- a/net/bluetooth/hci_conn.c Sun Mar 7 18:39:38 2004 +++ b/net/bluetooth/hci_conn.c Sun Mar 7 18:39:38 2004 @@ -170,6 +170,9 @@ hci_conn_hash_add(hdev, conn); tasklet_enable(&hdev->tx_task); + if (hdev->notify) + hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); + return conn; } @@ -195,6 +198,9 @@ /* Unacked frames */ hdev->acl_cnt += conn->sent; } + + if (hdev->notify) + hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); tasklet_disable(&hdev->tx_task); hci_conn_hash_del(hdev, conn); diff -Nru a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c --- a/net/bluetooth/hci_core.c Sun Mar 7 18:39:37 2004 +++ b/net/bluetooth/hci_core.c Sun Mar 7 18:39:37 2004 @@ -189,6 +189,10 @@ /* Mandatory initialization */ + /* Reset */ + if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks)) + hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL); + /* Read Local Supported Features */ hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL); diff -Nru a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c --- a/net/bluetooth/hci_event.c Sun Mar 7 18:39:36 2004 +++ b/net/bluetooth/hci_event.c Sun Mar 7 18:39:36 2004 @@ -232,6 +232,9 @@ hdev->voice_setting = setting; BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); + + if (hdev->notify) + hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); } break; @@ -247,6 +250,9 @@ hdev->voice_setting = setting; BT_DBG("%s: voice setting 0x%04x", hdev->name, setting); + + if (hdev->notify) + hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); } hci_req_complete(hdev, status); break; diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c --- a/net/bluetooth/rfcomm/core.c Sun Mar 7 18:39:36 2004 +++ b/net/bluetooth/rfcomm/core.c Sun Mar 7 18:39:36 2004 @@ -50,7 +50,7 @@ #include #include -#define VERSION "1.1" +#define VERSION "1.2" #ifndef CONFIG_BT_RFCOMM_DEBUG #undef BT_DBG @@ -409,7 +409,7 @@ return len; } -void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) +void fastcall __rfcomm_dlc_throttle(struct rfcomm_dlc *d) { BT_DBG("dlc %p state %ld", d, d->state); @@ -420,7 +420,7 @@ rfcomm_schedule(RFCOMM_SCHED_TX); } -void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) +void fastcall __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) { BT_DBG("dlc %p state %ld", d, d->state); diff -Nru a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c --- a/net/bluetooth/rfcomm/tty.c Sun Mar 7 18:39:37 2004 +++ b/net/bluetooth/rfcomm/tty.c Sun Mar 7 18:39:37 2004 @@ -50,6 +50,8 @@ #define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */ #define RFCOMM_TTY_MINOR 0 +static struct tty_driver *rfcomm_tty_driver; + struct rfcomm_dev { struct list_head list; atomic_t refcnt; @@ -98,6 +100,8 @@ rfcomm_dlc_put(dlc); + tty_unregister_device(rfcomm_tty_driver, dev->id); + /* Refcount should only hit zero when called from rfcomm_dev_del() which will have taken us off the list. Everything else are refcounting bugs. */ @@ -239,8 +243,11 @@ if (err) { kfree(dev); return err; - } else - return dev->id; + } + + tty_register_device(rfcomm_tty_driver, dev->id, NULL); + + return dev->id; } static void rfcomm_dev_del(struct rfcomm_dev *dev) @@ -871,8 +878,6 @@ /* ---- TTY structure ---- */ -static struct tty_driver *rfcomm_tty_driver; - static struct tty_operations rfcomm_ops = { .open = rfcomm_tty_open, .close = rfcomm_tty_close, @@ -906,7 +911,7 @@ rfcomm_tty_driver->minor_start = RFCOMM_TTY_MINOR; rfcomm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; rfcomm_tty_driver->subtype = SERIAL_TYPE_NORMAL; - rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW; + rfcomm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; rfcomm_tty_driver->init_termios = tty_std_termios; rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; tty_set_operations(rfcomm_tty_driver, &rfcomm_ops); diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c --- a/net/ipv4/igmp.c Sun Mar 7 18:39:38 2004 +++ b/net/ipv4/igmp.c Sun Mar 7 18:39:38 2004 @@ -105,7 +105,8 @@ #include #endif -#define IP_MAX_MEMBERSHIPS 20 +#define IP_MAX_MEMBERSHIPS 20 +#define IP_MAX_MSF 10 #ifdef CONFIG_IP_MULTICAST /* Parameter names and values are taken from igmp-v2-06 draft */ @@ -1325,6 +1326,7 @@ * Join a socket to a group */ int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS; +int sysctl_igmp_max_msf = IP_MAX_MSF; static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, @@ -1790,6 +1792,10 @@ } /* else, add a new source to the filter */ + if (psl && psl->sl_count >= sysctl_igmp_max_msf) { + err = -ENOBUFS; + goto done; + } if (!psl || psl->sl_count == psl->sl_max) { struct ip_sf_socklist *newpsl; int count = IP_SFBLOCK; diff -Nru a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c --- a/net/ipv4/ip_sockglue.c Sun Mar 7 18:39:37 2004 +++ b/net/ipv4/ip_sockglue.c Sun Mar 7 18:39:37 2004 @@ -618,6 +618,7 @@ case IP_MSFILTER: { extern int sysctl_optmem_max; + extern int sysctl_igmp_max_msf; struct ip_msfilter *msf; if (optlen < IP_MSFILTER_SIZE(0)) @@ -636,9 +637,14 @@ kfree(msf); break; } - if (IP_MSFILTER_SIZE(msf->imsf_numsrc) < - IP_MSFILTER_SIZE(0) || - IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) { + /* numsrc >= (1G-4) overflow in 32 bits */ + if (msf->imsf_numsrc >= 0x3ffffffcU || + msf->imsf_numsrc > sysctl_igmp_max_msf) { + kfree(msf); + err = -ENOBUFS; + break; + } + if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) { kfree(msf); err = -EINVAL; break; diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c --- a/net/ipv4/sysctl_net_ipv4.c Sun Mar 7 18:39:37 2004 +++ b/net/ipv4/sysctl_net_ipv4.c Sun Mar 7 18:39:37 2004 @@ -39,6 +39,7 @@ /* From igmp.c */ extern int sysctl_igmp_max_memberships; +extern int sysctl_igmp_max_msf; /* From inetpeer.c */ extern int inet_peer_threshold; @@ -411,6 +412,14 @@ }, #endif + { + .ctl_name = NET_IPV4_IGMP_MAX_MSF, + .procname = "igmp_max_msf", + .data = &sysctl_igmp_max_msf, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, { .ctl_name = NET_IPV4_INET_PEER_THRESHOLD, .procname = "inet_peer_threshold", 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 Mar 7 18:39:37 2004 +++ b/net/sunrpc/auth_gss/svcauth_gss.c Sun Mar 7 18:39:37 2004 @@ -594,12 +594,13 @@ iov.iov_len = sizeof(xdr_seq); xdr_buf_from_iov(&iov, &verf_data); p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len; + mic.data = (u8 *)(p + 1); maj_stat = gss_get_mic(ctx_id, 0, &verf_data, &mic); if (maj_stat != GSS_S_COMPLETE) return -1; - p = xdr_encode_netobj(rqstp->rq_res.head->iov_base - + rqstp->rq_res.head->iov_len, &mic); - kfree(mic.data); + *p++ = htonl(mic.len); + memset((u8 *)p + mic.len, 0, round_up_to_quad(mic.len) - mic.len); + p += XDR_QUADLEN(mic.len); if (!xdr_ressize_check(rqstp, p)) return -1; return 0; diff -Nru a/sound/oss/Makefile b/sound/oss/Makefile --- a/sound/oss/Makefile Sun Mar 7 18:39:37 2004 +++ b/sound/oss/Makefile Sun Mar 7 18:39:37 2004 @@ -68,7 +68,7 @@ obj-$(CONFIG_SOUND_BT878) += btaudio.o obj-$(CONFIG_SOUND_ALI5455) += ali5455.o ac97_codec.o obj-$(CONFIG_SOUND_IT8172) += ite8172.o ac97_codec.o -obj-$(CONFIG_SOUND_FORTE) += forte.o +obj-$(CONFIG_SOUND_FORTE) += forte.o ac97_codec.o obj-$(CONFIG_SOUND_AD1980) += ac97_plugin_ad1980.o obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o diff -Nru a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c --- a/sound/oss/ac97_plugin_ad1980.c Sun Mar 7 18:39:36 2004 +++ b/sound/oss/ac97_plugin_ad1980.c Sun Mar 7 18:39:36 2004 @@ -123,3 +123,4 @@ module_init(ad1980_init); module_exit(ad1980_exit); +MODULE_LICENSE("GPL"); diff -Nru a/sound/oss/cs46xx_wrapper-24.h b/sound/oss/cs46xx_wrapper-24.h --- a/sound/oss/cs46xx_wrapper-24.h Sun Mar 7 18:39:37 2004 +++ b/sound/oss/cs46xx_wrapper-24.h Sun Mar 7 18:39:37 2004 @@ -28,7 +28,7 @@ #include -#define CS_OWNER owner: +#define CS_OWNER .owner = #define CS_THIS_MODULE THIS_MODULE, void cs46xx_null(struct pci_dev *pcidev) { return; } #define cs4x_mem_map_reserve(page) SetPageReserved(page) diff -Nru a/sound/oss/emu10k1/cardwi.c b/sound/oss/emu10k1/cardwi.c --- a/sound/oss/emu10k1/cardwi.c Sun Mar 7 18:39:37 2004 +++ b/sound/oss/emu10k1/cardwi.c Sun Mar 7 18:39:37 2004 @@ -164,7 +164,6 @@ if (alloc_buffer(card, &wiinst->buffer) < 0) { ERROR(); - emu10k1_wavein_close(wave_dev); return -1; } diff -Nru a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c --- a/sound/oss/sb_audio.c Sun Mar 7 18:39:38 2004 +++ b/sound/oss/sb_audio.c Sun Mar 7 18:39:38 2004 @@ -882,7 +882,7 @@ c -= locallen; p += locallen; } /* used = ( samples * 16 bits size ) */ - *used = len << 1; + *used = max_in > ( max_out << 1) ? (max_out << 1) : max_in; /* returned = ( samples * 8 bits size ) */ *returned = len; }